Search code examples
c#stack-tracethrowrethrow

Incorrect stacktrace by rethrow


I rethrow an exception with "throw;", but the stacktrace is incorrect:

static void Main(string[] args) {
    try {
        try {
            throw new Exception("Test"); //Line 12
        }
        catch (Exception ex) {
            throw; //Line 15
        }
    }
    catch (Exception ex) {
        System.Diagnostics.Debug.Write(ex.ToString());
    }
    Console.ReadKey();
}

The right stacktrace should be:

System.Exception: Test
   at ConsoleApplication1.Program.Main(String[] args) in Program.cs:Line 12

But I get:

System.Exception: Test
   at ConsoleApplication1.Program.Main(String[] args) in Program.cs:Line 15

But line 15 is the position of the "throw;". I have tested this with .NET 3.5.


Solution

  • Throwing twice in the same method is probably a special case - I've not been able to create a stack trace where different lines in the same method follow each other. As the word says, a "stack trace" shows you the stack frames that an exception traversed. And there is only one stack frame per method call!

    If you throw from another method, throw; will not remove the entry for Foo(), as expected:

      static void Main(string[] args)
      {
         try
         {
            Rethrower();
         }
         catch (Exception ex)
         {
            Console.Write(ex.ToString());
         }
         Console.ReadKey();
      }
    
      static void Rethrower()
      {
         try
         {
            Foo();
         }
         catch (Exception ex)
         {
            throw;
         }
    
      }
    
      static void Foo()
      {
         throw new Exception("Test"); 
      }
    

    If you modify Rethrower() and replace throw; by throw ex;, the Foo() entry in the stack trace disappears. Again, that's the expected behavior.