+3  A: 

You could throw a new exception, placing the exception e as an inner exception. Then read the stacktrace of the inner exception.

Shiraz Bhaiji
I can read the stack trace as a string just fine, but when I need to navigate through the call stack to figure out what went wrong, I have no choice but to manually find the file and line of each item in the call stack.
Mark Rushakoff
So what is missing from Visual Studio that should be there? I guess that is my question.
sixlettervariables
+2  A: 

Visual Studio will show the call stack of the place where it stops.

In the case of an unhandled exception, it will stop where that exception is thrown. i.e. your "throw" statement. But if your code handles the exception, then Visual Studio assumes you know what you're doing, and ignores the exception. It will only catch the exception when it is re-thrown in Main() because you aren't handling it in your program.

If you want to catch the original exception in visual studio, you have two options:

  • don't catch the exception in your code. Visual Studio by default will only stop at unhandled exceptions. This of course means your program won't handle exceptions at runtime, so isn't a very useful approach!

  • use your code to catch and re-throw the exception (as you are doing), but configure Visual Studio to stop when the inner exception is first thrown. Go to Debug>Exceptions and tick the "common language runtime" exceptions box (to stop for any exception) or browse the subtree to enable exception catching for specific exceptions (hint: if you know the exception name, hit the Find... button and enter part of the name, e.g. "FileNotFound", to quickly find the exception). This will make VS stop at the inner exception, and only move on to your catch{} statement if you choose to continue execution after examining the exception details.

Jason Williams
this is the answer. masterful. just purely masterful.
djmc
+1  A: 

If I understand your message, there is confusion (maybe not by you, but by others reading your message) between the stack trace of the error which is correct and the current call stack at a particular point in time (which is not what you want)

However, once you get into your exception handling routine, the Foo routine has finished and so I can't see how it could be part of your current call stack.

Apart from enabling 'break at first exception' , I can't see how this would work and am not aware of anything in VS2003 or VS2005 which will help this. (Maybe the new debugging/replay features in VS2010)

sgmoore
+1, took a while to figure out it was the Call Stack Window.
sixlettervariables
There was confusion (mostly/all on my part) about the stack trace of a re-thrown exception. The `StackTrace` property of the exception is correct, but I'd like to make VS break and allow me to navigate through the call stack as though I hadn't caught the exception at all. I understand your point about `Foo` having finished and temporary variables no longer existing, though. I'll probably have to put the try-catch in a separate branch of an if statement, as I mentioned in the edit at the top of the question. Just keeping it open for if someone knows another approach, now.
Mark Rushakoff
+1  A: 

What you're describing is the expected behavior of the Call Stack window. When Visual Studio breaks at the throw line due to an UnhandledException, it is correct to have the call stack show starting at the throw line.

It boils down to Visual Studio's Call Stack Window isn't aware of the stack trace contained in your exception.

sixlettervariables
+1, I had incorrectly believed that the empty `throw` would act as though I never caught the exception at all. I'm keeping the question open for a bit to see if anyone *does* know a way to trick VS into operating that way, otherwise I'll probably be accepting your answer.
Mark Rushakoff
+3  A: 

It turns out that if you know the right terms to search, there is an answer to the problem I was trying to solve. In MSIL, it's called exception filtering, and it is available in VS2003.

In Visual Basic.NET, there is a construct called "catch-when" that will only execute a catch when a given predicate passes. This MSDN blog has a great example of how catch-when works in VB.NET vs. the results (like mine) of C#'s catch-throw.

Finally, MSDN has a tool called Exception Filter Inject that can be used to "provide exception filter support for languages (such as C#) which do not have exception filter support" - the catch is that it runs on an existing assembly, so it does introduce an awkward stage in the build process if you end up using it.


Before I found Exception Filter Inject, I ended up implementing a short function that took a "functional" delegate and a "catch" delegate, and would just call the functional if exceptions were allowed to bubble up, otherwise called the functional in a try-catch, calling the catch delegate on a caught exception.

What I wanted to do, that somehow lead me to find exception filtering, was to be able to set the type of the exception to catch at runtime - if exceptions were supposed to bubble up, I would have tried catching a subclassed Exception that would never be invoked, otherwise I would have just caught a basic Exception. I'm really not sure if that would have been possible in .NET 1.1 or not, since that basically would require a generic -- but it may have been possible with Reflection, I just never got that far in my research.

Mark Rushakoff