Go to home page mail me! RSS Feed

Re-throwing an exception

Monday, November 05, 2007 9:06 PM

This is one of those "Yeah I've always seen people use it differently but I don't know why!" questions. Re-throwing exceptions can be misused, although it may not cause any harm to your application - there are multiple ways of re-throwing an exception, most likely for the purpose of bubbling it up to a higher level. Note to Java developers: It is different in your world.

Lets look at how many ways we can use throw:

    1. throw
    2. throw ex
    3. throw new Exception(); 

You should not use #3 except if you are throwing a specific exception other that the one that was fired such as a custom exception. To re-throw an exception in .NET your best option is #1 instead of #2 and that is simply because of how they stack up in the stack trace. Lets take a look at the stack trace for both instances using the following snippet.

 

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            DoMath();
        }
        catch(Exception ex)
        {
            throw ex;
        }
    }

    /// <summary>
    /// A method that simply calls another method.
    /// </summary>
    /// <remarks>
    /// Just a helper to show stack trace
    /// </remarks>
    private void DoMath()
    {
        MethodWithError();
    }

    /// <summary>
    /// This method will throw an error
    /// </summary>
    private void MethodWithError()
    {
        throw new Exception("Generic exception");
    }

 

The stack trace looks like this:

[Exception: Generic exception]
   throwerror.Page_Load(Object sender, EventArgs e) 
in d:\My Websites\demoweb\throwerror.aspx.cs:22
   System.Web.Util.CalliHelper.EventArgFunctionCaller
(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback
(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, 
Boolean includeStagesAfterAsyncPoint) +1061

 

However, if I replace "throw ex;" with just "throw;", here is the new stack trace.

 

[Exception: Generic exception]
   throwerror.MethodWithError() in d:\My Websites\demoweb\throwerror.aspx.cs:42
   throwerror.DoMath() in d:\My Websites\demoweb\throwerror.aspx.cs:34
   throwerror.Page_Load(Object sender, EventArgs e) in d:\My Websites\demoweb\throwerror.aspx.cs:22
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061

 

Its all about the details. Obviously, using just "throw;" gives us much more details - so use "throw" to re-throw an error.

Your Comments.

  • # re: Re-throwing an exception

    GravatarNot sure that your example "gives us much more details"?

    "Throw ex;" will reset the stack trace and it will appear that the exception originates with in the try block. This makes it more difficult to track to the source of the exception, "MethodWithError()".

    Left by Grunt at 11/6/2007 9:52 AM
  • # re: Re-throwing an exception

    GravatarThe additional information that it provides helps "track to the source of the exception" as you stated.

    Left by Rydal at 11/6/2007 10:35 AM
  • # re: Re-throwing an exception

    GravatarIf you handle your own exceptions... a good practice to give you more information about what happened, you can do:

    throw new MyCustomException("my message", ex);

    that way...the other exception will still be available through "InnerException" and you will have a custom message explaining what the hell went wrong.

    Left by Maxim at 11/29/2007 8:26 PM
  • # re: Re-throwing an exception

    GravatarCool that is good to know, thats me changing the code standards at my place ^^

    Left by Dancoe at 11/30/2007 5:29 AM
  • # re: Re-throwing an exception

    GravatarThe solution generaly recomended in most of the books I read "throw;" is not the best one for rethrowing because it also destroys a part of the stack information..

    I've blog about it so in case you care check it out

    http://blog.vuscode.com/malovicn/archive/2007/04/01/gotcha-improper-exception-handling.aspx

    Left by Nikola Malovic at 11/30/2007 7:44 AM
  • # re: Re-throwing an exception

    GravatarI prefer the use of a custom exception class that i can include a InnerException information that the new Custom Exception could manage.

    This way i can't loose any info about the stack..

    Left by Javier Romero at 11/30/2007 11:45 AM
  • # re: Re-throwing an exception

    Gravatar

    I started doing it this way simply because I was not using the exception and VS kept warning me about the unused variable during compilation, so there is another reason to just call throw.

    Left by Brennan Stehling at 11/30/2007 1:16 PM
  • # re: Re-throwing an exception

    Gravatar
    I started doing it this way simply because I was not using the exception and VS kept warning me about the unused variable during compilation, so there is another reason to just call throw.

    Left by Brennan Stehling at 11/30/2007 1:17 PM
  • # re: Re-throwing an exception

    GravatarAnother important point -- make sure you avoid *catching* the exception if you're simply going to rethrow it with no further processing. It's a pretty general rule for exceptions -- either you can handle it (so you catch it) or you can't (so you just let it keep going) or you have important information to add (so you wrap it -- preserving the source exception! -- and throw the wrapping exception).

    And yes, definitely make sure you don't discard a stack trace.... I worked with a group of developers some years ago where it had become common practice (simply through lack of thought, I think) to always catch exceptions, then throw a *new* exception like this (in Java, but you'll see the flaw):
    throw new Exception("error: " + ex.toString());

    It was horrible. When debugging you'd know it was a NullPointer, for example, but you'd have no clue where it was since the original stack trace was discarded -- so a 2 minute fix became slow, painful detective work for no good reason....

    Left by Rob W at 12/3/2007 10:29 AM
  • # re: Re-throwing an exception

    Gravatar By the way, there's somehting strange going on with the comment system here -- i get javascript warnings when submitting the comment, then an error page....

    Left by Rob W at 12/3/2007 10:33 AM
  • # re: Re-throwing an exception

    GravatarThanks, Rob W. I'll check it out.

    Left by Rydal at 12/3/2007 1:06 PM
  • # re: Re-throwing an exception

    GravatarYour post solved my problem... thank you Sir...

    Left by custom net development at 9/22/2008 8:22 AM
  • # re: Re-throwing an exception

    GravatarIf you do, the Exception you throw will have a stack frame starting at the current point, i.e. the logging block, and not where it was originally thrown. Rather, you should use the throw; syntax <a href-"http://www.top-poker-game.com/">Poker Online Game

    Left by Poker online game at 7/14/2009 4:20 AM

Your Reply.

Comment Form.

Fields denoted with a "*" are required.

You may also like to leave your email or website.

 
Please add 1 and 1 and type the answer here:

Preview Your Comment.

 
Next entries »