Steve Smith's Blog

Musings on Software and the Developer Community

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 throw
                                DoSomething();
 
#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:

image

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.

    kick it on DotNetKicks.com

Monday, 07 July 2008

Comments

 avatar

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();

});


 avatar

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?


 avatar

sandeep said on 04 Nov 2008 at 4:07 PM

This is really a great solution for xmlparser exception.Thanks


 avatar

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