none
Rethrowing exception reset the stack? RRS feed

  • Question

  • Everywhere you can read about how is bad to throw new exception without specifying the original one as the inner exception.
    Something like this:
        catch (Exception ex)
        {
            throw ex;
        }

    but if you write:
        catch (Exception ex)
        {
            throw;
        }

    the rethrown exception is the same one was catched in the last 'catch' block.

    But try this code:

    1   void Func() 
    2   { 
    3       try 
    4       { 
    5           try 
    6           { 
    7                throw new Exception("some error"); 
    8           } 
    9           catch (Exception ex) 
    10          { 
    11              throw; 
    12          } 
    13     } 
    14     catch (Exception ex1) 
    15     { 
    16         Debug.Write(ex1); 
    17     } 
    18 } 


    The stack of ex1 points to line 11. Not to 7, like stack of ex. I expected it will point to line 7, because the exception was rethrowed.

    So the question is: Is this a bug or a feature?

    Wednesday, July 23, 2008 9:26 AM

Answers

  • This is likely due to an implementation detail in the JIT compiler.  Stackwalks are produced from the exception address and the return addresses on the stack frames, mapping them back to a source file name and line number.  There is no "extra" stack frame or return address when code progresses from one catch block to another within the same stack frame.  Technical limitation would be a more forgiving term than bug.

    This is not likely to get fixed anytime soon, if at all.  Breaking up the catch blocks across two methods would be an obvious solution.  Not using catch + throw but just a finally block to cleanup solves the problem too.  Plus InnerException of course.

    Hans Passant.
    • Marked as answer by Kamarey Wednesday, July 23, 2008 7:23 PM
    Wednesday, July 23, 2008 5:03 PM
    Moderator

All replies

  • If I am not wrong, its not about the line number, but the preservation of stack.

    The difference is that throw; preserves the original stack trace and throw ex; truncates the stack trace below the method in which the throw ex; call is located.

    So if you check the stack trace with throw; statement, you should get the reference to line 7 as well along with 11

    --
    Madhur

    http://blogs.msdn.com/mahuja | Please mark the replies as answers if they help
    Wednesday, July 23, 2008 11:14 AM
  • The question is exactly about what you say: you don't get the line 7. You will not see it anywhere in exception. Just try it yourself.
    Wednesday, July 23, 2008 11:43 AM
  • This is likely due to an implementation detail in the JIT compiler.  Stackwalks are produced from the exception address and the return addresses on the stack frames, mapping them back to a source file name and line number.  There is no "extra" stack frame or return address when code progresses from one catch block to another within the same stack frame.  Technical limitation would be a more forgiving term than bug.

    This is not likely to get fixed anytime soon, if at all.  Breaking up the catch blocks across two methods would be an obvious solution.  Not using catch + throw but just a finally block to cleanup solves the problem too.  Plus InnerException of course.

    Hans Passant.
    • Marked as answer by Kamarey Wednesday, July 23, 2008 7:23 PM
    Wednesday, July 23, 2008 5:03 PM
    Moderator
  • Thanks for reply.
    Now I understand the problem, but think the best in this case is just throw the catched exception 'as is' without updating its line number. If someone need the line the exception was rethrown from, he can wrap the original exception with a new one. Asked this question because was unable to find any information on web regarding this issue, what is strange. So lets leave this 'undocumented feature' as 'technical limitation'.

    Thanks
    Wednesday, July 23, 2008 7:22 PM