Visual studio used to have a specific checkbox to \"Break on Un-handled exception\". In 2015 this has been removed (or moved somewhere I cannot find it). So now my convert
Microsoft have subtly changed the logic in the new exceptions window.
See http://blogs.msdn.com/b/visualstudioalm/archive/2015/02/23/the-new-exception-settings-window-in-visual-studio-2015.aspx
The key part being:
Important Notes
- This new window contains all of the same functionality as the old modal dialog. No capabilities of the debugger have changed only the way you can access them
- The debugger will always break when an exception is unhandled
- The setting to change if the debugger breaks on user-unhandled exceptions has moved under a context menu
- The menu location has moved to Debug -> Windows -> Exception Settings
However, if like me you have a Global Unhandled Exception Handler in your code then the second item on that list is key: For me, no exceptions will therefore be truly unhandled, which seems to be different from VS2013.
To get back the behaviour where VS breaks on unhandled exceptions, I had to tick all of the exception types I wanted to break on and then secondly ensure that the "Additional Options" (you may need to make this column visible*) for "Continue when unhandled in user code" was NOT set. The VS2015 logic does not seem to consider my Global Unhandled Exception Handler to be "handled in user code", so it does break on these; it doesn't break on caught exceptions though. This makes it work like VS2013 did.
*How to enable the "Additional Actions" column
It's all a bit confusing, and in my opinion not as good as the old exceptions dialog, but anyway.
If an exception is in the list and ticked then the debugger will break whenever the exception is thrown.
If an exception is unticked or not in the list then the debugger will only break when that exception type is user unhandled.
For example, in the screenshot below, the debugger will break whenever a System.AccessViolationException
is thrown, but for all the other exceptions it will only break if the exception was user unhandled.
The solution is to this is semantically the opposite to what you think you are setting. You need to ensure that Continue when unhandled in user code is not enabled i.e. not checked as shown under the Additional Actions column in the Exception settings tab - see below:
you are effectively saying do not continue (i.e. break) when unhandled in code
To do this:
That did it for me - happy again.
This was in VS 2015
In my experience the exception settings in 2015 get thrown completely out of whack if you change anything.
On expect that if you until the parent group "CLR" then you shouldn't get any breaking execpt for unhandled. You'll always break if an exception goes unhandled. But, if you have the CLR group unticked, code inside a try...catch simply should not cause a break. That is NOT the case.
Solution: In the new exception settings toolbox, right-click and choose "restore default". Taadaaaa... It behaves normally again. Now don't screw with it.
Visual Studio 2017 works just fine with error handling. Visual Studio 2015 on the other hand sucks at error handling with tasks because in debug mode all exceptions that occur in an async task are caught but then if I step over it just hangs indefinitely. If executed without debugging it hangs indefinitely with no exception caught!!! I love visual studio and have been using it since 1995 and 2015 is the worse version by far though I jumped from 2010 directly to 2015. I spent 8 hours trying to get this exception handling working with no success. I copied the exact code to 2017 on my home computer and it worked perfectly. I am very irritated that Microsoft pushed tasks into a framework that the 2015 compiler can't handle correctly.
If I'm correctly reading between the lines here, the issue is that your exception is effectively 'disappearing' even though the default debugger behavior should break on unhandled exceptions.
If you have asynchronous methods, you may be running into this issue because exceptions not caught on a thread pool thread as part of a Task continuation are not considered unhandled exceptions. Rather, they are swallowed and stored with the Task.
For example, take a look at this code:
class Program
{
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
private async static Task Test()
{
await Task.Delay(100);
throw new Exception("Exception!");
}
}
If you run this program with the default debugger settings (stop on unhandled exceptions only), the debugger will not break. This is because the thread pool thread allocated to the continuation swallows the exception (passing it to the Task instance) and releases itself back to the pool.
Note that, in this case, the real issue is that the Task
returned by Test()
is never checked. If you have similar types of 'fire-and-forget' logic in your code, then you won't see the exceptions at the time they are thrown (even if they are 'unhandled' inside the method); the exception only shows up when you observe the Task by awaiting it, checking its Result or explicitly looking at its Exception.
This is just a guess, but I think it's likely you're observing something like this.