Capture exception state

Using ExceptionDispatchInfo to capture exception state

Home DailyDrop

Daily Knowledge Drop

When catching an exception, the ExceptionDispatchInfo class can be used to capture the state of the exception. This can then later be used to throw the original exception, preserving its original state.


Use case

The ExceptionDispatchInfo class is used in the situation where an exception occurs and is caught, but additional processing has to occur before the exception can be thrown up the call stack.

The following examples will clear when and why to use ExceptionDispatchInfo.

Using Exception

First we'll look at an example without using ExceptionDispatchInfo.

NullReferenceException tempException = null;

try
{
    List<int> nullList = null;

    nullList.Add(100);
}
catch(NullReferenceException exception)
{
    tempException = exception;
}

// Do additional processing here
// maybe save information to database
// perhaps some logging

if(tempException != null)
{
    // Maybe do some cleanup processing here

    throw tempException;
}

In this sample, an exception occurs and is caught, but additional processing needs to be done before exiting the function. Here the exception is saved into a variable (tempException), which is then thrown when the additional processing has been done.

The output of the above highlights the issue with this approach:

Unhandled exception. System.NullReferenceException: 
        Object reference not set to an instance of an object.
   at Program.<Main>$(String[] args) in 
    C:\Development\Blog\ExceptionDispatchInfoDemo\
            ExceptionDispatchInfoDemo\Program.cs:line 22

According to the output the exception occurred on line 22. This is NOT accurate - the exception occurred on line 7, but when the exception is thrown on line 22, the state of the original exception is not being preserved.

Using this approach, its difficult to track down the actual root cause of the exception. ExceptionDispatchInfo helps solve this problem.


Using ExceptionDispatchInfo

This sample is very similar to the above one, except the exception is captured into an instance of ExceptionDispatchInfo instead of saved into a variable.

using System.Runtime.ExceptionServices;

ExceptionDispatchInfo exceptionDispatchInfo = null;

try
{
    List<int> nullList = null;

    nullList.Add(100);
}
catch (NullReferenceException exception)
{
    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception);
}

// Do additional processing here
// maybe save information to database
// perhaps some logging

if (exceptionDispatchInfo != null)
{
    // Maybe do some cleanup processing here

    exceptionDispatchInfo.Throw();
}

When the exception occurs, it is captured into the instance of ExceptionDispatchInfo. Then on line 24, the instance of ExceptionDispatchInfo is used to throw the captured exception.

The output now looks as follows:

Unhandled exception. System.NullReferenceException: 
        Object reference not set to an instance of an object.
   at Program.<Main>$(String[] args) in C:\Development\Blog\
        ExceptionDispatchInfoDemo\ExceptionDispatchInfoDemo\Program.cs:line 9
--- End of stack trace from previous location ---
   at Program.<Main>$(String[] args) in C:\Development\Blog\
        ExceptionDispatchInfoDemo\ExceptionDispatchInfoDemo\Program.cs:line 24

Here we can see that the exception originated on line 9 - we now have accurate information, allowing the exception root cause to easily be traced!


Notes

Having to always do additional processing after an exception is caught, but before the exception is thrown, is not a very common use case. However when it is required, the ExceptionDispatchInfo class can easily be used to ensure no valuable exception information is lost.


References

11. ExceptionDispatchInfo

Daily Drop 67: 05-05-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net exception exceptiondispatchinfo