Preserving the Stack Trace

by Marcel Veldhuizen 21. February 2013 16:11

Rethrowing Exceptions

Normally, if you have to rethrow and existing exception in .NET, you should use the throw keyword without any parameters:

try
{
    // Code that can generate exceptions here
}
catch (Exception ex)
{
    // Do some logging or whatever
    throw;
}

Using throw ex; would cause the stack trace of the exception to be lost, in which case we lose some valuable information. However, this only works inside the catch block that caught the exception in the first place.

Sometimes, you need to rethrow the exception at a later point outside the catch block, but of course we want to preserve the stack trace.

.NET Framework 4.5

If you're using .NET 4.5, you're in luck. One of the new features is built-in support for preserving the stack trace, by using the new ExceptionDispatchInfo class.

ExceptionDispatchInfo exceptionDispatchInfo = null;

try
{
    // Code that can generate exceptions here
}
catch (Exception ex)
{
    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);
}

// Do whatever in between

if (exceptionDispatchInfo != null)
    exceptionDispatchInfo.Throw();

Older Versions

If you're using a somewhat older version of the framework, you can still achieve something similar:

using System;
using System.Reflection;

static class ExceptionExtensions
{
    public static void PreserveStackTrace(this Exception exception)
    {
        MethodInfo preserveStackTrace = typeof(Exception).GetMethod(
            "InternalPreserveStackTrace",
            BindingFlags.Instance | BindingFlags.NonPublic);

        preserveStackTrace.Invoke(exception, null);
    }
}

This code uses reflection to call an internal method InternalPreserveStackTrace, which means you must run with a high enough trust level to allow for this. It's used like so:

Exception exception = null;

try
{
    // Code that can generate exceptions here
}
catch (Exception ex)
{
    ex.PreserveStackTrace();
    exception = ex;
}

// Do whatever in between

if (exception != null)
    throw exception;

Conclusions

If you're only targeting .NET 4.5, using ExceptionDispatchInfo is clearly preferred, because it does not require a high trust environment and it also stores some additional information about the exception that normally gets lost: the "Watson buckets".

If you are writing code for .NET 4.0 or earlier, but plan to move to 4.5 later, you could consider implementing your own ExceptionDispatchInfo in very much the same way as the extension method above.

Tags: , ,

.NET

Comments (7) -

Javier Barriuso Spain
2/13/2014 5:08:51 AM #

Really interesting article, and very usefull too. I will implement this structure cause actually I have not all the trace info when catching and throwing exceptions. Thank you! Smile

Reply

foot fetish vids United States
11/25/2016 2:38:41 AM #

I have been checking out many of your posts and i must say clever stuff. I will make sure to bookmark your website.

Reply

Juan
1/28/2017 11:06:03 AM #

I have applied the above code in my website you can check here https://www.webdesigngenie.co.uk/ but it didn't workout and I think I need to double check it.

Reply

Porno United States
2/16/2017 9:02:37 AM #

Hi there mates, pleasant article and good urging commented at this place, I am really enjoying by these.

Reply

Chota Bhim
4/7/2017 2:17:55 PM #

Enjoying this post ;) <a href=”https://bhimapps.us” target=”_blank”>Bhim App</a

Reply

Chota Bhim
4/7/2017 2:19:41 PM #

<a href=”https://bhimapps.us” target=”_blank”>Bhim App</a>

Reply

Masjali
4/17/2017 2:45:39 AM #

Terimakasih informasinya.mantab selalu

Reply

Add comment

Marcel Veldhuizen

Software Architect by profession, mostly focused on Microsoft .NET technology.

Metal enthusiast; I love going to concerts :)

 

RecentPosts

Recent Tweets

Note: For Customization and Configuration, CheckOut Recent Tweets Documentation