3

In my codebase I have some retry functionality that stores an exception in a variable and at the end throws the exception in the variable. Imagine something like this

Exception exc = null;

while(condition){
   try {
      // stuff
   } catch (Exception e){
     exc = e;
   }
}

if (e != null){
   throw e;
}

Now, since this is a throw e statement and not a throw statement, the original stack trace is lost. Is there some way to do a rethrow that preserves the original stack trace, or will I need to restructure my code so I can use a throw statement?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
MrZarq
  • 258
  • 3
  • 12
  • [InnerException](https://learn.microsoft.com/en-us/dotnet/api/system.exception.innerexception)? – Sinatr Nov 19 '20 at 14:19
  • But then I lose my Type info, so exception handlers that look at the type will not see the original type. – MrZarq Nov 19 '20 at 14:20
  • Wouldn't the original exception `e` contain the stack trace in its `StackTrace` property? – arconaut Nov 19 '20 at 14:21
  • 1
    The accepted answer [here](https://stackoverflow.com/questions/57383/how-to-rethrow-innerexception-without-losing-stack-trace-in-c) might help. – Klaus Gütter Nov 19 '20 at 14:24

1 Answers1

7

That's where ExceptionDispatchInfo comes into play.
It resides inside the System.Runtime.ExceptionServices namespace.

class Program
{
    static void Main(string[] args)
    {
        ExceptionDispatchInfo edi = null;

        try
        {
            // stuff
            throw new Exception("A");
        }
        catch (Exception ex)
        {
            edi = ExceptionDispatchInfo.Capture(ex);
        }

        edi?.Throw();
    }
}

The output:

Unhandled exception. System.Exception: A
   at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 16
--- End of stack trace from previous location where exception was thrown ---
   at EDI_Demo.Program.Main(String[] args) in C:\Users\...\Program.cs:line 24
  • Line 16 is where throw new Exception("A"); is called
  • Line 24 is where edi?.Throw(); is called
Peter Csala
  • 17,736
  • 16
  • 35
  • 75