Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / programming / exceptions

Dynamically Intercepting Thrown Exceptions with LinFu.AOP 2.0

0.00/5 (No votes)
4 May 2011LGPL32 min read 7.7K  
How to dynamically intercept thrown exceptions with LinFu.AOP 2.0

exception

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:

C#
<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:

C#
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);

        // This line tells LinFu.AOP to swallow the thrown exception;
        // By default, LinFu will just rethrow the exception
        exceptionHandlerInfo.ShouldSkipRethrow = true;
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Hook the sample exception handler into the application
        ExceptionHandlerRegistry.SetHandler(new SampleExceptionHandler());

        var account = new BankAccount(100);

        // Without LinFu's dynamic exception handling, the 
        // next line of code will cause the app to crash:
        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:

C#
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.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)