- Posted by justin on August 26, 2006
Interesting article on the differences between throw and throw ex. http://mattgollob.blogspot.com/
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. For example, here's some driver code and the generated output:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 ThrowSample ts = new ThrowSample();
6
7 try { ts.ThrowMethod(); }
8 catch(Exception ex)
9 {
10 Trace.WriteLine(
11 "Exception caught from ThrowMethod:");
12 Trace.WriteLine(ex.ToString());
13 }
14
15 try { ts.ThrowExMethod2(); }
16 catch (Exception ex)
17 {
18 Trace.WriteLine(
19 "Exception caught from ThrowExMethod:");
20 Trace.WriteLine(ex.ToString());
21 }
22 }
Output:
Exception caught from ThrowMethod:
System.Exception: DOH!
at ThrowSample.ThrowSample.ExceptionMethod() in
C:\ThrowSample\Program.cs:line 55
at ThrowSample.ThrowSample.ThrowMethod() in
C:\ThrowSample\Program.cs:line 38
at ThrowSample.Program.Main(String[] args) in
C:\ThrowSample\Program.cs:line 14
Exception caught from ThrowExMethod:
System.Exception: DOH!
at ThrowSample.ThrowSample.ThrowExMethod() in
C:\ThrowSample\Program.cs:line 48
at ThrowSample.Program.Main(String[] args) in
C:\ThrowSample\Program.cs:line 21
Notice how the stack trace from the ThrowMethod() call includes ThrowSample.ThrowSample.ExceptionMethod()? This portion of the stack is conspicuously absent from the ThrowExMethod() stack trace.
Now, we're lucky we've got the PDBs handy so we get line numbers in the exception message. What if we didn't? It certainly would be harder to find the true source of the exception using the stack trace from throw ex;, especially if the ThrowExMethod method was more complicated than it is.
Let's take this one step further, and assume there are several method calls between ThrowExMethod and ExceptionMethod, any or all of which could be throwing their own exceptions. Using the stack trace from throw ex; there'd be no wayy to know where the exception actually came from. See why it's important to understand the difference?
All that being said, using throw ex; isn't always bad. But you should only be using it when you have something to add to the exception that was caught. In which case, you should be throwing a new exception instance, initialized with the caught exception as the inner exception. For example:
1 public void ThrowExMethod2()
2 {
3 try { this.ExceptionMethod(); }
4 catch (Exception ex)
5 {
6 // Log the exception
7 throw new ApplicationException(
8 "Uh-oh!", ex);
9 }
10 }
Now the stack trace is nicely preserved:
Exception caught from ThrowExMethod:
System.ApplicationException: Uh-oh! ---> System.Exception: DOH!
at ThrowSample.ThrowSample.ExceptionMethod() in
C:\ThrowSample\Program.cs:line 65
at ThrowSample.ThrowSample.ThrowExMethod2() in
C:\ThrowSample\Program.cs:line 54
--- End of inner exception stack trace ---
at ThrowSample.ThrowSample.ThrowExMethod2() in
C:\ThrowSample\Program.cs:line 58
at ThrowSample.Program.Main(String[] args) in
C:\ThrowSample\Program.cs:line 21