I've got something like this:
try
{
instance.SometimesThrowAnUnavoidableException(); // Visual Studio pauses the execution here due to the CustomException and I want to prevent that.
}
catch (CustomException exc)
{
// Handle an exception and go on.
}
anotherObject.AlsoThrowsCustomException(); // Here I want VS to catch the CustomException.
In another part of code I have multiple occurencies of situations where CustomException is thrown. I would like to force the Visual Studio to stop breaking on instance.SometimesThrowAnUnavoidableException() line cause it obscures the view of other places where I'm interested in breaking on CustomException.
I tried DebuggerNonUserCode but it is for a different purpose.
How to disable Visual Studio from catching particular exception only in a certain method?
You can use custom code to do this in two steps.
Disable automatic breaking on the CustomException exception.
Add a handler for the AppDomain.FirstChanceException event to your application. In the handler, if the actual exception is a CustomException, check the call stack to see if you actually want to break.
Use the Debugger.Break(); to cause Visual Studio to stop.
Here is some example code:
private void ListenForEvents()
{
AppDomain.CurrentDomain.FirstChanceException += HandleFirstChanceException;
}
private void HandleFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Exception ex = e.Exception as CustomException;
if (ex == null)
return;
// option 1
if (ex.TargetSite.Name == "SometimesThrowAnUnavoidableException")
return;
// option 2
if (ex.StackTrace.Contains("SometimesThrowAnUnavoidableException"))
return;
// examine ex if you hit this line
Debugger.Break();
}
In Visual Studio, go to debug->exceptions and turn off breaking for your CustomException by unchecking the appropriate checkbox, then set a breakpoint in the code (probably on the catch statement) on the places you actually want to break on.
If you want Visual Studio to stop breaking on all exceptions of a type, you have to configure the behavior from the Exceptions window.
Full instructions are here, but the gist is to go to the Debug menu and choose exceptions, then uncheck the items you dont want the debugger to break on.
I don't think there is a way to avoid a specific method using this technique, but maybe the better question is "why is this throwing an exception?"
You could add a set of #IF DEBUG pre-processor instructions to avoid running the problematic sections of code.
You can disable stepping altogether by placing the DebuggerStepThrough Attribute before the method.
As this disables stepping in the whole method, you may isolate the try-catch into a seperate one for debugging purposes.
I did not test, but it should not even break in that method when en exception is thrown. Give it try ;-)
See also this SO thread
You can't simply disable Visual Studio from stoping in a particular place of code. You can only prevent it to stop when particular type of exception is thrown but that will affect all places where such exception occurs.
Actually you can implement custom solution as suggested by 280Z28.
Related
I would like Visual Studio to break when a handled exception happens (i.e. I don't just want to see a "First chance" message, I want to debug the actual exception).
e.g. I want the debugger to break at the exception:
try
{
System.IO.File.Delete(someFilename);
}
catch (Exception)
{
//we really don't care at runtime if the file couldn't be deleted
}
I came across these notes for Visual Studio.NET:
1) In VS.NET go to the Debug Menu >>
"Exceptions..." >> "Common Language
Runtime Exceptions" >> "System" and
select "System.NullReferenceException"
2) In the bottom of that dialog there
is a "When the exception is thrown:"
group box, select "Break into the
debugger"
3) Run your scenario. When the
exception is thrown, the debugger will
stop and notify you with a dialog that
says something like:
"An exception of type "System.NullReferenceException" has
been thrown.
[Break] [Continue]"
Hit [Break]. This will put you on the
line of code that's causing the
problem.
But they do not apply to Visual Studio 2005 (there is no Exceptions option on the Debug menu).
Does anyone know where the find this options dialog in Visual Studio that the "When the exception is thrown" group box, with the option to "Break into the debugger"?
Update: The problem was that my Debug menu didn't have an Exceptions item. I customized the menu to manually add it.
With a solution open, go to the Debug - Windows - Exception Settings (Ctrl+Alt+E) menu option. From there you can choose to break on Thrown or User-unhandled exceptions.
EDIT: My instance is set up with the C# "profile" perhaps it isn't there for other profiles?
There is an 'exceptions' window in VS2005 ... try Ctrl+Alt+E when debugging and click on the 'Thrown' checkbox for the exception you want to stop on.
Took me a while to find the new place for expection settings, therefore a new answer.
Since Visual Studio 2015 you control which Exceptions to stop on in the Exception Settings Window (Debug->Windows->Exception Settings). The shortcut is still Ctrl-Alt-E.
The simplest way to handle custom exceptions is selecting "all exceptions not in this list".
Here is a screenshot from the english version:
Here is a screenshot from the german version:
From Visual Studio 2015 and onward, you need to go to the "Exception Settings" dialog (Ctrl+Alt+E) and check off the "Common Language Runtime Exceptions" (or a specific one you want i.e. ArgumentNullException) to make it break on handled exceptions.
Step 1
Step 2
Check Managing Exceptions with the Debugger page, it explains how to set this up.
Essentially, here are the steps (during debugging):
On the Debug menu, click Exceptions.
In the Exceptions dialog box, select Thrown for an entire category of exceptions, for example, Common Language Runtime Exceptions.
-or-
Expand the node for a category of exceptions, for example, Common Language Runtime Exceptions, and select Thrown for a specific exception within that category.
A technique I use is something like the following. Define a global variable that you can use for one or multiple try catch blocks depending on what you're trying to debug and use the following structure:
if(!GlobalTestingBool)
{
try
{
SomeErrorProneMethod();
}
catch (...)
{
// ... Error handling ...
}
}
else
{
SomeErrorProneMethod();
}
I find this gives me a bit more flexibility in terms of testing because there are still some exceptions I don't want the IDE to break on.
The online documentation seems a little unclear, so I just performed a little test. Choosing to break on Thrown from the Exceptions dialog box causes the program execution to break on any exception, handled or unhandled. If you want to break on handled exceptions only, it seems your only recourse is to go through your code and put breakpoints on all your handled exceptions. This seems a little excessive, so it might be better to add a debug statement whenever you handle an exception. Then when you see that output, you can set a breakpoint at that line in the code.
There are some other aspects to this that need to be unpacked. Generally, an app should not throw exceptions unless something exceptional happens.
Microsoft's documentation says:
For conditions that are likely to occur but might trigger an exception, consider handling them in a way that will avoid the exception.
and
A class can provide methods or properties that enable you to avoid making a call that would trigger an exception.
Exceptions degrade performance and disrupt the debugging experience because you should be able to break on all exceptions in any running code.
If you find that your debugging experience is poor because the debugger constantly breaks on pointless exceptions, you may need to detect handled exceptions in your tests. This technique allows you to fail tests when code throws unexpected exceptions.
Here are some helper functions for doing that
public class HandledExceptionGuard
{
public static void DoesntThrowException(Action test,
Func<object?, Exception, bool>? ignoreException = null)
{
var errors = new List<ExceptionInformation>();
EventHandler<FirstChanceExceptionEventArgs> handler = (s, e) =>
{
if (e.Exception is AssertFailedException) return;
if (ignoreException?.Invoke(s, e.Exception) ?? false) return;
errors.Add(new ExceptionInformation(s, e.Exception, AppDomain.CurrentDomain.FriendlyName));
};
AppDomain.CurrentDomain.FirstChanceException += handler;
test();
AppDomain.CurrentDomain.FirstChanceException -= handler;
if (errors.Count > 0)
{
throw new ExceptionAssertionException(errors);
}
}
public async static Task DoesntThrowExceptionAsync(Func<Task> test,
Func<object?, Exception, bool>? ignoreException = null)
{
var errors = new List<ExceptionInformation>();
EventHandler<FirstChanceExceptionEventArgs> handler = (s, e) =>
{
if (e.Exception is AssertFailedException) return;
if (ignoreException?.Invoke(s, e.Exception) ?? false) return;
errors.Add(new ExceptionInformation(s, e.Exception, AppDomain.CurrentDomain.FriendlyName));
};
AppDomain.CurrentDomain.FirstChanceException += handler;
await test();
AppDomain.CurrentDomain.FirstChanceException -= handler;
if (errors.Count > 0)
{
throw new ExceptionAssertionException(errors);
}
}
}
If you wrap any code in these methods as below, the test will fail when a handled exception occurs. You can ignore exceptions with the callback. This validates your code against unwanted handled exceptions.
[TestClass]
public class HandledExceptionTests
{
private static void SyncMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
}
}
private static async Task AsyncMethod()
{
try
{
await Task.Run(() => throw new Exception());
}
catch (Exception)
{
}
}
[TestMethod]
public void SynchronousTest()
{
HandledExceptionGuard.DoesntThrowException(() => SyncMethod());
}
[TestMethod]
public async Task AsyncTest()
{
await HandledExceptionGuard.DoesntThrowExceptionAsync(() => AsyncMethod());
}
}
Visual Studio 2017 is (kind of suddenly) breaking on all exceptions. That means, if I deactivate them in the exceptions settings (pressing CTRL + ALT + E while debugging), the debugger still breaks on them. I don't know wether this is just a bug of VS I can't change and therefore have to live with, or wether there is a simple solution for it.
This is the exception settings window:
and this the exception VS breaks on:
By the way, I also tried that beautiful minus (nothing happens if I press it) or adding a impossible condition (VS still broke on the exception).
I also tested other exceptions (by simply throwing them), which I deactivated before, and they get thrown as well and I tested the same issue in other projects, where it appeared as well:
I actually even put the whole stuff into a try catch statement but VS still breaks:
InitializeComponent ();
try
{
var t = new Thread (() =>
{
while (!IsHandleCreated) {} //It breaks here (similiar to the screenshots)
while (true)
Invoke (new Action (() => Size = new Size ()));
});
while (true)
{
t.Start ();
Thread.Sleep (100);
t.Abort ();
}
}
catch (ThreadAbortException) { }
It doesn't appear in other IDEs (like Rider) on my PC and doesn't occurr on other PCs in VS. It didn't always occurr on my PC, it just started recently and only in debugging mode. And if I continue the execution (with F5) it just continues normally.
EDIT As I put the try catch inside the thread it behaved a little bit different (I'm sorry for putting pictures in here, but I think they're more expressive in that case):
Can anybody explain this behaviour?
EDIT It seems to be normal for ThreadAbortExceptions to break again at the end of a catch statement. However, VS still shouldn't break on this exception at all.
I was having a similar problem.
I fixed it by unchecking "Break when exceptions cross AppDomain or managed/native boundaries" in Tools > Options > Debugging > General
I fixed it by unchecking Enable Just My Code in Tools > Options > Debugging > General
I can't confirm whether this happens with other project types, but it happens to me consistently with (Visual Studio Tools for Python) VSTP.
Although it is less than satisfactory, it can at least silence the exceptions and allow you to continue working in peace until a better solution surfaces. In my case, it was nearly impossible to debug my code, since StopIteration breaks during every iteration.
Select Debug > Windows > Exception Settings or press Ctrl-Alt-E. Y
Right click anywhere on the Window and select Show Columns > Additional Actions. You will have an "Additional Actions" column appear if it doesn't already.
Right click on a specific exception you want to silence or click the top level checkbox to select an entire category of exceptions, i.e. Python Exceptions. Click Continue When Unhandled in User Code.
Repeat for each additional exception or category of exceptions.
I know it's a little late for this, but ThreadAbortException is different from all other exceptions, and requires some special handling, otherwise it is automatically re-thrown at the end of all catch blocks if you don't actually handle it the way it's supposed to be handled.
Here's a code reproducing the behavior I'm expecting to get:
static void Main(string[] args)
{
// try // #2
{
string x = null; // #1
AssertNotNull(x, nameof(x));
}
// catch (ArgumentNullException) { } // #2
Console.WriteLine("Passed.");
Console.ReadKey();
}
[DebuggerHidden]
public static void AssertNotNull<T>(T arg, string argName) where T : class
{
if (arg == null)
throw new ArgumentNullException(argName);
}
The behavior is the same for any VS starting from VS2008 (did not check on earlier versions).
If you run it under debug (using a standard debugging settings) you're not allowed to continue until you fix the code (using the EnC). Hitting F5 will just rerun assertion due to [DebuggerHidden] and "Unwind stack on unhandled exception" setting combo (setting is enabled by default).
To fix the code, just replace the #1 line with object x = "", set the next statement to it and hit F5 again.
Now, enable "break when thrown" for the ArgumentNullException and uncomment the lines marked with #2.
The behavior changes: you're stopped on assertion again, but the stack does not unwind (easy to check with CallStack window). F5 will continue from the place the exception was thrown.
Ok, so... now the question is:
Is there any way to enable auto stack unwinding when breaking on handled exceptions?
Hidden VS option, existing extension or (maybe) API that can be used from my own extension?
UPD: To clarify the question: I want to break at the line with failed assertion, edit the code with edit and continue, set next statement to the fixed code and continue the execution.
As it works if the exception is not caught down the stack.
UPD2 As proposed by Hans Passant: Posted an suggestion on UserVoice. Feel free to vote:)
and uncomment the lines marked with #2
This is the critical part of your question. You changed more than one thing, the critical change is that you altered the way the stack is unwound. The debugger option you like is titled "Unwind stack on unhandled exception". Problem is, there is no unhandled exception anymore. Your catch clause handles it and it is now the CLR that unwinds the stack.
And it must be the CLR that does the unwinding, the debugger does not have an option to do it on the first-chance exception break that you asked for. And SetNext can't work at that point. Which, if I interpret the question correctly, you would really like to have since what you need to do next is busy work, single stepping through the catch block is not enormous joy.
Although it is not implemented, I think it is technically do-able. But only because I'm blissfully unaware how much work the debugger team will have to do. It is a good ask to make E+C work better, you can propose it here. Post the URL to your proposal as a commnent and good odds it will get a bunch of votes. I'll vote for it.
To clarify the question: I want to break at the line with failed
assertion, edit the code with edit and continue, set next statement to
the fixed code and continue the execution.
Open the "Exception Settings" Menu (Debug > Windows > Exception Settings)
Under "Common Language Runtime Exceptions", check the box for "System.ArgumentNullException". (Or check them all, whatever you're looking for.)
It should now break whenever a System.ArgumentNullException is thrown, regardless if it will be caught in a catch block.
However, you cannot edit and continue active statements. If you try to modify your assertion line, you'll see something like this:
I have the following C# code:
try
{
response = this.writeDataToChannel(writeRequest);
if (response.Failures != null)
{
Console.WriteLine(response.Failures.First().cause);
}
}
catch (TimeoutException te)
{
Console.Error.WriteLine(te.Message);
}
When I run this code in release and push a lot of data to the service, VS2010 stops on the "writeDataToChannel" line with a TimeoutException. Shouldn't my catch block catch the exception and just print it when the timeout happens?
The "writeDataToChannel" code was generated from a WSDL, the writes always work until I push tons of data to the webservice, so I don't think there is a problem with my request.
It is not a namespace issue, in both cases it is a System.TimeoutException.
It sounds to me like you have Visual Studio set to stop on a thrown exception. Go to the menu item Debug->Exceptions and see what your CLR Exceptions settings are. To get the behavior that you're describing, you don't want to stop on caught or uncaught exceptions.
Alternatively, don't run it under the debugger.
You probably need to tell VS to not break on each thrown exception in the exceptions dialog (ctrl + alt + e and uncheck CLR exceptions)
As others have mentioned, this happens when you are debugging the project (by hitting F5, or clicking the green triangle button ">").
To run without debugging, type CTRL + F5, or click the "Start without debugging" menu choice or button.
You don't necessarily need to remove the option to stop on exceptions like others have mentioned, but go ahead and do so if it becomes annoying.
You will need to throw in order to catch something in your try/catch
throw
I want to be able to break on Exceptions when debugging... like in Visual Studio 2008's Menu Debug/Exception Dialog, except my program has many valid exceptions before I get to the bit I wish to debug.
So instead of manually enabling and disabling it using the dialog every time is it possible to do it automatically with a #pragma or some other method so it only happens in a specific piece of code?
The only way to do something close to this is by putting the DebuggerNonUserCodeAttribute on your method.
This will ensure any exceptions in the marked method will not cause a break on exception.
Good explanation of it here...
This is an attribute that you put against a method to tell the debugger "Nothing to do with me guv'. Ain't my code!". The gullible debugger will believe you, and won't break in that method: using the attribute makes the debugger skip the method altogether, even when you're stepping through code; exceptions that occur, and are then caught within the method won't break into the debugger. It will treat it as if it were a call to a Framework assembly, and should an exception go unhandled, it will be reported one level up the call stack, in the code that called the method.
Code example:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
What about conditional breakpoints? If I understand correctly, you can have a breakpoint fire only when the value of a certain variable or expression is true.
Wrap your try catch blocks in #if DEBUG
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
I like to keep the curly braces outside of the #if that way it keeps the code in the same scope if inside or outside of debug.
If you still want the execption handeling but want more detail you can do this
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
This is a bit of too late for you, but this is the biggest reason I often try to teach people to use exceptions conservatively. Only use exceptions when something catastrophic has happened and your ability to reasonably continue is gone.
When debugging a program I often flip on First Chance Exceptions (Debug -> Exceptions) to debug an application. If there are a lot of exceptions happening it's very difficult to find where something has gone "wrong".
Also, it leads to some anti-patterns like the infamous "catch throw" and obfuscates the real problems. For more information on that see a blog post I made on the subject.
In terms of your problem, you can turn on first chance debugging for only a specific type of exception. This should work well unless the other exceptions are of the same type.
You could also use asserts instead of breakpoints. For instance, if you only want to breakpoint on the 5th iteration of a loop on the second time you call that function, you could do:
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
So in the first call to Work, while breakLoop is false, the loop will run through without asserting, the second time through the loop will break.