Visual Studio Break When Exception Thrown
By default, Visual Studio will only break when an exception is unhandled in user code. This is often some distance from where the actual exception took place, as several try...catch blocks might have been involved in the meantime before the exception goes unhandled. A recent thread on the ALT.NET mailing list discussed some techniques for getting round this issue if you the developer would really like to see exactly the line of code that is failing. One such technique (Jon Davis) used precompilation directives to conditionally add the try-catch statements, like so:
void MyMethod(){#if !DEBUG try {#endif // the logic that might throwDoSomething();
#if !DEBUG}
catch (Exception e) {LogError(e);
// etc…}
#endif}
This gets pretty ugly fast, but it gets the job done. However, another list member (Nick Blumhardt) wrote in and pointed out a feature of Visual Studio that effectively does this for you if it's the desired behavior. From the Debug menu, choose Exceptions (or use Ctrl-Alt-E) which brings up this dialog:
If you check the box under Thrown for Common Language Runtime Exceptions, the debugger will break on the line where it occurs rather than when it goes unhandled in some catch block. The downside to using this option is that it applies to all code, not just a particular method. You can mix and match the two techniques if you only want certain code blocks to break when the exception is thrown, but personally I would avoid the former technique as I think it results in uglier code that is less clear, and doesn't behave the same under development as in production.
It's also worth pointing out that Visual Basic can use Catch Exception When {expression} to achieve this quite easily. For instance, a DEBUG flag could be used for the When condition. This would still result in code that differs in behavior between DEBUG and production, but at least it's far more elegant and easier to read and maintain. C#, unfortunately, lacks such a feature.




Comments
Peter Ritchie said on 08 Jul 2008 at 4:35 PM
You could abstract the try/catch into a method and use anonymous methods to avoid many conditional statements:
#if DEBUG
public static void LogExceptions(MethodInvoker func)
{
try
{
func();
}
catch(Exception e)
{
LogError(e);
throw;
}
}
#else
public static void LogExceptions(MethodInvoker func)
{
func();
}
#endif
//...
LogExceptions(delegate {
DoSomething();
});
Justas said on 09 Jul 2008 at 5:08 PM
When I press Ctrl-Alt-E, the exceptions window does open, however the "User-Unhandled" column is not there. Only the "name" and "thrown" columns are there.
I tried right-clicking the column names, but I don't see any option to show that column. Same if I try it while debugging or not. Mine is a web-application project.
Any ideas why it's not there?
sandeep said on 04 Nov 2008 at 4:07 PM
This is really a great solution for xmlparser exception.Thanks
Fabrice said on 11 Jan 2009 at 5:25 PM
Justas, I had the same problem and I noticed that the "User-Unhandled" column is missing when "Just my code" is disabled.
To get the column back, "Enable Just My Code" needs to be unchecked.
See here to learn how to change this: http://msdn.microsoft.com/en-us/library/h5e30exc(VS.80).aspx