In the past I worked on an application which used modules from different teams. Many of these modules raised and caught a ton of exceptions. So much so that performance data was showing that these exceptions were causing issues. So I had to figure out an easy way to programmatically find out these code and inform their owners that exception is for exceptional scenarios and shouldn't be used for normal code-flow :)
Thankfully CLR provides an easy hook in the form of an AppDomain event. I just need to hook into the AppDomain.FirstChanceException event and CLR notifies upfront when the exception is raised. It does that even before any managed code gets a chance to handle it (and potentially suppresses it).
The following is a plugin which throws and catches exception.
namespace Plugins
{
public class FunkyPlugin
{
public static void ThrowingFunction()
{
try
{
Console.WriteLine("Just going to throw");
throw new Exception("Cool exception");
}
catch (Exception ex)
{
Console.WriteLine("Caught a {0}", ex.Message);
}
}
}
}
In the main application I added code to subscribe to the FirstChanceException event before calling the plugins
using System;
using System.Runtime.ExceptionServices;
using System.Reflection;
namespace foo
{
public class Program
{
static void Main()
{
// Register handler
AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;
Plugins.FunkyPlugin.ThrowingFunction();
}
static void FirstChanceHandler(object o,
FirstChanceExceptionEventArgs e)
{
MethodBase site = e.Exception.TargetSite;
Console.WriteLine("Thrown by : {0} {1}({2})", site.Module,
site.DeclaringType,
site.ToString());
Console.WriteLine("Stack: {0}", e.Exception.StackTrace);
}
}
}
The FirstChanceHandler just dumps out the name of the assembly and type that raises the exception. The output of this program is as follows
Read more: Bong Geek