Best practices for catching and re-throwing .NET exceptions

前端 未结 11 1482
野的像风
野的像风 2020-11-22 07:15

What are the best practices to consider when catching exceptions and re-throwing them? I want to make sure that the Exception object\'s InnerException

相关标签:
11条回答
  • 2020-11-22 07:55

    The rule of thumb is to avoid Catching and Throwing the basic Exception object. This forces you to be a little smarter about exceptions; in other words you should have an explicit catch for a SqlException so that your handling code doesn't do something wrong with a NullReferenceException.

    In the real world though, catching and logging the base exception is also a good practice, but don't forget to walk the whole thing to get any InnerExceptions it might have.

    0 讨论(0)
  • 2020-11-22 07:57

    FYI I just tested this and the stack trace reported by 'throw;' is not an entirely correct stack trace. Example:

        private void foo()
        {
            try
            {
                bar(3);
                bar(2);
                bar(1);
                bar(0);
            }
            catch(DivideByZeroException)
            {
                //log message and rethrow...
                throw;
            }
        }
    
        private void bar(int b)
        {
            int a = 1;
            int c = a/b;  // Generate divide by zero exception.
        }
    

    The stack trace points to the origin of the exception correctly (reported line number) but the line number reported for foo() is the line of the throw; statement, hence you cannot tell which of the calls to bar() caused the exception.

    0 讨论(0)
  • 2020-11-22 08:01

    If you throw a new exception with the initial exception you will preserve the initial stack trace too..

    try{
    } 
    catch(Exception ex){
         throw new MoreDescriptiveException("here is what was happening", ex);
    }
    
    0 讨论(0)
  • 2020-11-22 08:02

    When you throw ex, you're essentially throwing a new exception, and will miss out on the original stack trace information. throw is the preferred method.

    0 讨论(0)
  • 2020-11-22 08:03

    The way to preserve the stack trace is through the use of the throw; This is valid as well

    try {
      // something that bombs here
    } catch (Exception ex)
    {
        throw;
    }
    

    throw ex; is basically like throwing an exception from that point, so the stack trace would only go to where you are issuing the throw ex; statement.

    Mike is also correct, assuming the exception allows you to pass an exception (which is recommended).

    Karl Seguin has a great write up on exception handling in his foundations of programming e-book as well, which is a great read.

    Edit: Working link to Foundations of Programming pdf. Just search the text for "exception".

    0 讨论(0)
  • 2020-11-22 08:06

    You should always use "throw;" to rethrow the exceptions in .NET,

    Refer this, http://weblogs.asp.net/bhouse/archive/2004/11/30/272297.aspx

    Basically MSIL (CIL) has two instructions - "throw" and "rethrow":

    • C#'s "throw ex;" gets compiled into MSIL's "throw"
    • C#'s "throw;" - into MSIL "rethrow"!

    Basically I can see the reason why "throw ex" overrides the stack trace.

    0 讨论(0)
提交回复
热议问题