A screenshot of LinFu dynamically catching a thrown exception
On Error, Resume Interception
Another useful thing that LinFu.AOP
allows you to do is to intercept (and rethrow) exceptions within your applications at runtime. LinFu makes it so easy, in fact, that all you have to do is add the following lines to your CSProj file:
<PropertyGroup>
<PostWeaveTaskLocation>
$(MSBuildProjectDirectory)\$(OutputPath)\..\..\..\lib\LinFu.Core.dll
</PostWeaveTaskLocation>
</PropertyGroup>
<UsingTask TaskName="PostWeaveTask" AssemblyFile="$(PostWeaveTaskLocation)" />
<Target Name="AfterBuild">
<PostWeaveTask TargetFile="$(MSBuildProjectDirectory)\$(OutputPath)$(MSBuildProjectName).dll"
InterceptAllExceptions="true" />
</Target>
Exceptionally Simple
To use LinFu.AOP
's dynamic exception handling capabilities, all you need to do is make the following call to handle all exceptions being thrown in your application:
public class SampleExceptionHandler : IExceptionHandler
{
public bool CanCatch(IExceptionHandlerInfo exceptionHandlerInfo)
{
return true;
}
public void Catch(IExceptionHandlerInfo exceptionHandlerInfo)
{
var exception = exceptionHandlerInfo.Exception;
Console.WriteLine("Exception caught: {0}", exception);
exceptionHandlerInfo.ShouldSkipRethrow = true;
}
}
class Program
{
static void Main(string[] args)
{
ExceptionHandlerRegistry.SetHandler(new SampleExceptionHandler());
var account = new BankAccount(100);
account.Deposit(100);
return;
}
}
Try/Catch Me, If You Can
The call to ExceptionHandlerRegistry.SetHandler
tells LinFu to hook the SampleExceptionHandler
into your application so that all exceptions that will be thrown will automatically be handled by the given exception handler. Under normal circumstances (where interception is disabled), the call to account.Deposit()
will cause the app to crash, but as this example shows, LinFu.AOP
was able to intercept the thrown exception before it could crash the rest of the app.
What makes this even more interesting, however, is the IExceptionHandlerInfo
instance that describes the context from which the exception was thrown:
public interface IExceptionHandlerInfo
{
Exception Exception { get; }
IInvocationInfo InvocationInfo { get; }
object ReturnValue { get; set; }
bool ShouldSkipRethrow { get; set; }
}
More Information Than You Can Throw An Exception At
The IExceptionHandlerInfo
interface has enough information to describe the method that caused the exception, as well as having properties such as ShouldSkipRethrow
that allow you to decide whether or not LinFu should just swallow the exception and keep running the program as if an exception was never thrown. The ReturnValue
property, in turn, allows you to alter the return value of a given method in case you want to resume the method and provide an alternate return value as if no exceptions were ever thrown.
As you can see, LinFu.AOP
makes it really easy to transparently handle exceptions in your applications, and if this post saves at least a few developers a few headaches from having to manually diagnose their applications, then I'd consider it to be a gratifying success.
Enjoy!
EDIT: You can get the code examples for LinFu.AOP
's dynamic exception handling here.