98

In tools/exceptions, I've set the option that the debugger stops when an exception is thrown. Whether it is caught or not .

How do I exclude an exception of that rule? Somewhere in my code there is a caught exception that is part of the program logic. So I obviously don't want that exception to stop the debugger each time it is hit.

Example: I want to ignore the nullreference exception (which is caught) on line 344 . I want to stop at all other exceptions

MichaelD
  • 8,377
  • 10
  • 42
  • 47
  • 6
    When this exception is part of your programming logic (think about, if you really have to implement it this way) - then it should be at least a own-created, derived exception. This way you can apply the solution of Brian. – tanascius Sep 14 '09 at 08:55
  • Here is the problem: http://stackoverflow.com/questions/1957907/how-do-i-know-when-a-lambda-expression-is-null – MichaelD Dec 24 '09 at 11:11
  • 2
    @tanascius - +1 I agree in most cases Exceptions are not the best way go about a logical decision; however in some cases like when deserializing handling exceptions is sometimes inevitable so throw>catch>handle is the only reasonable option. – jpierson Feb 07 '11 at 19:07
  • @Will: Visual Studio debugging "too localized" ? WTH? – Andomar Mar 03 '11 at 06:49
  • 2
    @Ando sorry my bad. Moderating multiple tabs at once is efficient, but not always accurate. –  Mar 03 '11 at 14:10
  • 3
    @tanascius: you may still have to catch a known framework exception before you can throw your own in response. Your suggestion isn't always possible. – Dan Puzey Aug 10 '12 at 07:35
  • @DanPuzey this case is very specific: MichaelD tells us he uses a NullReferenceException for programing logic. Instead of throwing such an exception he could check for a null pointer instead - and if necessary throw a custom exception. – tanascius Aug 10 '12 at 08:36

6 Answers6

70

DebuggerHidden is your friend!

The common language runtime attaches no semantics to this attribute. It is provided for use by source code debuggers. For example, the Visual Studio 2005 debugger does not stop in a method marked with this attribute and does not allow a breakpoint to be set in the method. Other debugger attributes recognized by the Visual Studio 2005 debugger are the DebuggerNonUserCodeAttribute and the DebuggerStepThroughAttribute.

Tested on VS2010 and works great.

While DebuggerStepThrough seems to also work for some specific debugger versions, DebuggerHidden seems to work for a wider range of situations based on the comments to both answers.

Note that both options do not currently work with iterator block methods or for async/await methods. This could be fixed in a later update of Visual Studio.

Note that it does not work with combination of .NET Core + Rider, you can vote the issue.

Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
  • working on VS2008. You have to apply it to the whole method including the catch block, or you'll just break somewhere else – Mark Heath Oct 28 '10 at 13:55
  • 2
    I added that attribute to a method and the debugger just stopped on the calling methond of it instead. Am I missing something? – Doogal Dec 17 '10 at 09:59
  • 1
    That's how it should be. to avoid that, you'll have to handle the exception... Or alternatively mark the caller method as `DebuggerHidden` as well... – Shimmy Weitzhandler Dec 17 '10 at 10:20
  • 1
    Note, that the DebuggerStepThrough attribute should be enough to avoid breaking on exceptions. DebuggerHidden acts like a combination of both DebuggerNonUserCode and the DebuggerStepThrough Attribute. – jpierson Feb 07 '11 at 19:33
  • 1
    Sadly, this [doesn't work if the method in question is an iterator method](http://stackoverflow.com/questions/11056478/how-to-combine-debuggerhidden-with-iterator-block-methods) :/ – Roman Starkov Jun 15 '12 at 18:43
  • Like Doogal, I found it wasn't working for me. The problem was that "Enable Just My Code (Managed Only)" must be checked, as described in Valery Letroye's answer below. – Tony Pulokas Sep 11 '14 at 19:34
  • It is not working in MSVS 2015: http://stackoverflow.com/questions/39382551 – crokusek Sep 08 '16 at 23:56
42

If I recall correctly you can use a DebuggerStepThrough attribute on the method that contains the code you don't want exception to fire. I suppose you can isolate the code that fires the annoying exception in a method and decorate it with the attribute.

Chris Chou
  • 668
  • 5
  • 4
  • 33
    From malinger's answer, and my experience, this answer appears to be incorrect. The `DebuggerStepThrough` attribute does not affect the debugger's behavior with first-chance exceptions. – Michael Petrotta Jan 28 '10 at 20:19
  • Yes you are right. I just tried it. I second tanascius on that it does seem a design issue. You can check if something is null first without tripping exceptions. – Chris Chou Feb 12 '10 at 02:09
  • +1 Adding DebuggerStepThrough attribute to a method in Visual Studio 2010 will prevent the debugger from halting an an unhandled exception is thrown by the method. – Tim Murphy Jul 13 '10 at 05:28
  • 6
    @Tim, I tested and it does NOT halt. checkout my answer: http://stackoverflow.com/questions/1420390/3455100#3455100 – Shimmy Weitzhandler Aug 11 '10 at 03:36
  • 1
    +1 works in VS2010 for pure .NET 4.0 and Silverlight 4 code for unhandled exceptions. – Mike Post Apr 07 '11 at 21:46
  • 6
    **Important note:** This doesn't work for async-await type methods. More [here](http://stackoverflow.com/q/24433331/885318) – i3arnon Jun 26 '14 at 14:51
  • 8
    Per MSDN, the `DebuggerStepThrough` attribute has no meaning to the CLR. It is interpreted by debuggers. It seems that it does not reliably work under a variety of circumstances, and that `DebuggerHidden` will work reliably http://stackoverflow.com/a/3455100/141172 – Eric J. Jul 14 '14 at 21:45
  • 1
    DebuggerStepThrough used to work for me. It does NOT any more in VS 2015. Anyone know how to get around this? – Matt Fitzmaurice Feb 10 '16 at 08:16
  • @MattFitzmaurice check out [this vs blog post](https://blogs.msdn.microsoft.com/visualstudioalm/2016/02/12/using-the-debuggernonusercode-attribute-in-visual-studio-2015/#) – bhh Mar 29 '16 at 09:54
14

DebuggerStepThrough is the one to be used to prevent the debugger to break in a method where there is a try/catch.

But it only works if you didn't uncheck the option "Enable Just My Code (Managed Only)" in the General settings of the Visual Studio's Debugging Options (menu Tools/Options, node Debugging/General)...

More info about that attribute on http://abhijitjana.net/2010/09/22/tips-on-debugging-using-debuggerstepthrough-attribute/

DebuggerHidden will simply prevent the Debugger to display the method where the exception is thrown. Instead, it will show the first method on the stack which is not marked with that attribute...

Valery Letroye
  • 1,035
  • 11
  • 19
  • 1
    Note that this no longer works by default in VS 2015, [see the VS blog for how to enable it](https://blogs.msdn.microsoft.com/visualstudioalm/2016/02/12/using-the-debuggernonusercode-attribute-in-visual-studio-2015/#) – bhh Mar 14 '16 at 14:34
  • Sadly the VS 2015 work-around doesn't work for VS 2019. – Jonathan Allen Dec 14 '19 at 21:52
14

The attributes specified in the other answers (and other ones such as DebuggerNonUserCode attribute) no longer work in the same way by default in Visual Studio 2015. The debugger will break on exceptions in methods market with those attributes, unlike in older versions of VS. To turn off the performance enhancement which changed their behaviour you need to change a registry setting:

reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1

More information can be found on the visual studio blog.

(This should probably be a comment on the top answer but I don't have enough rep)

bhh
  • 176
  • 1
  • 5
  • How do we re-enable the performance enhancement? – Sarath S Menon Jun 23 '22 at 10:58
  • 1
    I have not tested it, but I imagine `reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 0` (i.e. setting the final value to 0) will reenable it – bhh Jun 24 '22 at 11:40
3

You are not able to single out an exception thrown at a specific place in your code. You are however able to disable exeptions of a specific type.

If your own code throws the exception in question, i would make it a custom exception, derived from whatever fits, and then disable debug breaking on this derived type.

Disabling system exeptions as NullReferenceException will affect the entire system, which of course isnt desirable during development.

Note that there is two kinds of break-behaviors for exceptions:

  • Thrown: If selected, breaks as soon as a exception of this type is thrown
  • User-unhandled: If selected, breaks only if the exception, of this type, is not handled by a try/catch.

You could remove the check in 'Thrown' for the NullReferenceException which will give you the benefit of not breaking each time your system passes the line in question in your code, but still breaking if you have some unhandled NullReference expection occuring in other parts of the system.

Lars Udengaard
  • 1,227
  • 10
  • 21
  • 3
    Adding DebuggerStepThrough attribute to a method in Visual Studio 2010 will prevent the debugger from halting an an unhandled exception is thrown by the method. – Tim Murphy Jul 13 '10 at 05:30
  • 1
    I tested and it doesn't prevent; it still stops – Shimmy Weitzhandler Aug 11 '10 at 03:23
  • 1
    @Shimmy - Works for me! Make sure you are applying DebuggerStepThrough to each method from the point where it is thrown until the point you want the exception to become visible within the call stack. If you catch the exception and handle it within the call hierarchy where all methods are decorated with DebuggerStepThrough you should never see VS break on that exception. – jpierson Feb 07 '11 at 19:32
2

So I found a solution that works in VS 2019, it is a bit more complicated than I would like but for my use case it was necessary to solve this problem.

Instructions

First move the code that is causing the issue to its own function so you are not suppressing exceptions in surrounding code, and mark it with the DebuggerStepThrough attribute (or DebuggerHidden works too).

[DebuggerStepThrough]
public void ExceptionThrowingFunction()
{
    //.. Code that throws exception here
}

Then call it like this

OutsourceException(ExceptionThrowingFunction);

Then take either a separate project (module) that either you don't care about suppressing all exceptions in, or that is specifically created for this purpose. It is important that this is a separate project so that your main project can still break on this exception type. In my case I already had a small util project called SharedFunctions so I put it there. The code is pretty stable and does not need debugging most of the time.

In a class called ExceptionUtils I added the following functions:

public static T OutsourceException<T>(Func<T> func)
{
    T result = default;
    try
    {
        result = func.Invoke();
    }
    catch { }
    return result;
}

public static T OutsourceException<T, Y>(Func<T, Y> func, Y arg)
{
    T result = default;
    try
    {
        result = func.Invoke(arg);
    }
    catch { }
    return result;
}

public static void OutsourceException<T>(Action<T> action, T arg)
{
    try
    {
        action.Invoke(arg);
    }
    catch { }
}

You may need to add more of these, these cover just the basic cases where you have 0-1 arguments in your function.

Finally, when you run the code, it will still break on the exception in the Outsource function with a message like this: enter image description here If you check the bottom checkbox (in this example 'SharedFunctions.dll') it will add a rule that the exception should be ignored if thrown from that assembly. Once this is checked the exception should be suppressed. All other exceptions in the main assembly of this type will still break as normal.

What is happening here?

Due to the changes in VS 2015 that broke the [DebuggerHidden] and similar attributes (see the blog post linked in another answer here) the attributes now pass the exception to the calling class and the debugger simply breaks there. The if we move the calling class into another assembly we can suppress the exception using the exception conditions system.

Why not just fix the exception?

Some exceptions can't be removed from the code completely, for example when you try to access Package.Current in a UWP application. It will always throw an exception in the debugger, and this can only be resolved by microsoft. Another solution in this case is to just surround it with #if !DEBUG but there are other cases where this is not practical.

user3190036
  • 463
  • 6
  • 15