Best practices for catching and re-throwing .NET exceptions

Viewed 190231

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 and stack trace are preserved. Is there a difference between the following code blocks in the way they handle this?

try
{
    //some code
}
catch (Exception ex)
{
    throw ex;
}

Vs:

try
{
    //some code
}
catch
{
    throw;
}
11 Answers

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".

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);
}

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.

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.

I would definitely use:

try
{
    //some code
}
catch
{
    //you should totally do something here, but feel free to rethrow
    //if you need to send the exception up the stack.
    throw;
}

That will preserve your stack.

You may also use:

try
{
// Dangerous code
}
finally
{
// clean up, or do nothing
}

And any exceptions thrown will bubble up to the next level that handles them.

Related