When you catch and rethrow an exception, the stack is unwound by the time the catch clause is executed, and thus you may lose valuable information in the debugger.
Consider the following code snippet:
static void Main(string[] args) { Func1a(); } static void Func1a() { try { Func2(); } catch { throw; // rethrown, this goes unhandled } } static void Func2() { int x = 5; throw new Exception("Test"); // original first chance exception }
If you stop in the debugger when the exception is first thrown, you get the full callstack right at the throw point :
random.exe!Program.Func2() C# random.exe!Program.Func1b() C# random.exe!Program.Main(string[] args = {Dimensions:[0]}) C#
You can then use the full power of the debugger, such as inspecting parameters, locals, interceptable exceptions, mixed-mode callstacks (if interop-debugging), native assembly windows, etc.
However, if you stop at the catch/rethrow point, the stacktrace in the debugger is:
random.exe!Program.Func1b() C# random.exe!Program.Main(string[] args = {Dimensions:[0]}) C#
Now Func2(), the original throw site, is no longer on the stack in the debugger.
Other trivia:
catch (Exception e) { if (...) throw; else throw e; }
The callstack would be determined by the time you entered the catch block, and so would be the same in both cases.
The practical side: