This one does lose the initial site of the first exception, and throws it as a new exception at this location, centering the stack trace on this line.
This is what you want to do:
try { Throws(); } catch { DoHandling(); throw; }
Notice you do not name, or capture the exception. This causes your handling to execute, but crucially it re-throws the original exception untouched, with the original stack trace, centering on the original exception thrown location.
So you can easily lose that information if you re-throw naively. Good code tools should yell at you for doing this most of the time. Note in some cases you want to add information, so you can throw a new exception with new information, but set the InnerException property to the original causing exception.
This case is confusing and both you and the documentation are wrong. :)
You're confusing the Exception.StackTrace with the actual CLR stack trace. The minute you catch an exception in the CLR the accurate trace is destroyed. This is pathological for crash dumps, where it's imperative that you have an accurate trace for debugging.
If you don't believe me, go into VS and do the following.
1. Throw an exception.
2. Make sure that exception is not listed in exceptions to break on.
3. Catch and rethrow that exception using "throw;".
4. Let that exception filter out of the program unhandled.
5. Run in debugger.
Notice where your stack trace is centered on -- the "throw;" call.
I appreciate the further information, I did try this myself, and the difference is more clear now. The exception object had the StackTrace with the right info, but the debugger highlights the throw; line.
If the Exception.StackTrace has all the juicy details, why on earth not break there?
Yes, I was certainly thinking about the information available in the exception object itself. It's odd that it's set up this way, but I get it makes sense semantically, if other handler code has run, you need to trace things back yourself probably with a debugging step-through session, or turn on 'first chance exceptions' to get the most 'on the ground' information.
Yup, as I said, the problem is crash dumps. If this only affected debugging it would be a minor annoyance, but it destroys information in client crash dumps which get delivered by Watson, effectively making dumps useless.
Exception filters run before the stack is unrolled, so if you crash your process in an exception filter the stack is preserved.
... then fix the "throw;" call, don't bolt on a language feature to work around the fact that "throw;" mucks with the stack trace when it's not supposed to do that.
In one case you
try { Throws(); } catch(Exception ex) { DoHandling(); throw ex; } // BAD!
This one does lose the initial site of the first exception, and throws it as a new exception at this location, centering the stack trace on this line.
This is what you want to do:
try { Throws(); } catch { DoHandling(); throw; }
Notice you do not name, or capture the exception. This causes your handling to execute, but crucially it re-throws the original exception untouched, with the original stack trace, centering on the original exception thrown location.
So you can easily lose that information if you re-throw naively. Good code tools should yell at you for doing this most of the time. Note in some cases you want to add information, so you can throw a new exception with new information, but set the InnerException property to the original causing exception.
See http://msdn.microsoft.com/en-us/library/system.exception.inn...