Is there a difference between “throw” and “throw ex”?
Yes – throw re-throws the exception that was caught, and preserves the stack trace. throw ex throws the same exception, but resets the stack trace to that method. Unless you want to reset the stack trace (i.e. to shield public callers from the internal workings of your library), throw is generally the better choice, since you can see where the exception originated
In the “throw ex”, the stack trace is truncated, what this means is that when you look at the stack trace, it will look as if the exception originated in your code. This isn’t always the case, particularly if you are bubbling up a CLR generated exception (like a SqlException). This is a problem known as “breaking the stack”, because you no longer have the full stack trace information. This happens because you are in essence creating a new exception to throw.
By using “throw” by itself, you preserve the stack trace information. You can confirm this by looking at the IL generated for these two code blocks. This makes the difference very obvious since in the first example the IL instruction called is “throw” while in the second the instruction is called “rethrow”.
Before you run and change all of your code, there are still places where “throw ex” is appropriate. There are times when you want to add information to the exception that was caught or change it into a more meaningful exception.
- Only catch exceptions if they are important to you and you need to do some sort of cleanup as a result.
- If you need to bubble an exception up the chain, use “throw” by itself.
- If you need to add information to the exception or repackage it, always pass the original exception as the inner exception.