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());
}
}
Related
Setup:
1) MSVS 2015, Option -> Debugger -> "Just My Code" is checked.
2) This sample code placed within some class and called during startup:
static bool TestIgnoreException()
{
Exception ex;
return TrySomething(out ex);
}
[DebuggerNonUserCode] // Prevent exceptions from stopping the debugger within this method.
static bool TrySomething(out Exception exOut)
{
try
{
if (Environment. MachineName.Length != -1)
throw new Exception("ThrewIt.");
exOut = null;
return true;
}
catch (Exception ex)
{
exOut = ex;
return false;
}
}
3) Launch Debugger
Expected result is that TestIgnoreException() runs silently and returns false.
Actual result is the debugger stops in TestIgnoreException() even though there should be no exception being processed at that scope.
4) Also re-tried using [DebuggerHidden] instead, same results.
Motivation:
The motivation is for cases where some API that is out of your control does not provide a "Try" method and instead only indicates failure by using exceptions.
One of numerous such examples is .NET TcpClient.Connect(host, port). Say a program always tests some connections during startup, the debugger should not stop on this particular section of code each time.
Using the standard "break when thrown" exceptions checkboxes is is not good because it works globally by type. It cannot be configured to work locally. Also other developers who check out the code should automatically skip the exception as well.
Mystery solved. It is indeed a known issue that is new to MSVS 2015 because of added exception handling optimizations.
https://blogs.msdn.microsoft.com/visualstudioalm/2016/02/12/using-the-debuggernonusercode-attribute-in-visual-studio-2015/#
There is a workaround posted on that link to disable the optimizations and enable the old behavior. Hopefully they will eventually be able to revive the support for this including the optimizations.
reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1
Related question:
Don't stop debugger at THAT exception when it's thrown and caught
This question already has answers here:
Visual Studio: How to break on handled exceptions?
(8 answers)
Closed 8 years ago.
If I run the code below that calls Test1(), VS2012 will break nicely at that line and show me exactly what's going on. If I comment out Test1 and put in Test2, then the try catch does not stop on the line, it just logs it out to the console.
How can I get VS2012 to stop on the error line, even when it is surrounded by a try catch statement?
private void Button_Click(object sender, RoutedEventArgs e)
{
//Test1(); // No try catch - stops on error line dividing by zero.
Test2(); // Try catch - Just writes out to console.
}
private void MakeError()
{
int i = -1;
i += 1;
int j = 1 / i;
Console.WriteLine(j.ToString());
}
void Test1()
{
Console.WriteLine("MakeError in Test1");
MakeError();
}
void Test2()
{
Console.WriteLine("MakeError in Test2");
try
{
MakeError();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
While the other answers are correct, this is the intentional behavior by default, you can tell Visual Studio to alert you to those exceptions if you wish.
How to: Break When an Exception is Thrown:
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.
What you want is Visual Studio break execution when an exception is thrown:
On the Debug menu, click Exceptions.
In the Exceptions dialog box, select Thrown for an entire category of exceptions, for example (your case), Common Language Runtime Exceptions.
MSDN Reference.
Visual Studio will only intervene when there is an unhandled exception , in this case a division by 0. The try...catch handled the exception. Since there is no exception left unhandled, Visual Studio will not jump out.
try and catch statements are intended so that the flow of execution can still happen, even when an exception occurs. The debugger only stops when the exception is unhandled, which the try catch does.
This is intentional.
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.
Background
In my utilities library (Shd.dll) I have a class called AsyncOperation. To put it simply, it's a base class for types that encapsulate a potentially long running operation, executes it on a background thread, and it supports pause/resume, cancellation and progress reporting. (It's like a BackgroundWorker, just knows more things.)
In the user code you can use it like this:
class MyOperation : AsyncOperation
{
public MyOperation() : base(null, AsyncOperationOptions.Cancelable | AsyncOperationOptions.Pausable) {}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
operationState.ThrowIfCancelled();
}
}
var op = new MyOperation();
op.Start();
...
op.Cancel();
operationState.ThrowIfCancelled() does exactly what its name suggests: if Cancel() was called earlier by another thread, it throws an internal exception (AsyncOperationCancelException), which is then handled by the AsyncOperation type, like this:
private void _DoExecute(object state)
{
// note that this method is already executed on the background thread
...
try
{
operationDelegate.DynamicInvoke(args); // this is where RunOperation() is called
}
catch(System.Reflection.TargetInvocationException tiex)
{
Exception inner = tiex.InnerException;
var cancelException = inner as AsyncOperationCancelException;
if(cancelException != null)
{
// the operation was cancelled
...
}
else
{
// the operation faulted
...
}
...
}
...
}
This works perfectly. Or so I thought for the past year, while I was using this in numerous scenarios.
The actual problem
I'm building a class that uses System.Net.WebClient to upload potentially large number of files via FTP. This class is built using the AsyncOperation base class as described above.
For accurate progress reports, I use WebClient.UploadFileAsync(), which complicates the code, but the relevant parts look like this:
private ManualResetEventSlim completedEvent = new ManualResetEventSlim(false);
private void WebClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
...
if (OperationState.IsCancellationRequested)
{
_GetCurrentWebClient().CancelAsync();
}
}
private void WebClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
...
_UploadNextFile();
}
private void _UploadNextFile()
{
if (OperationState.IsCancellationRequested || ...)
{
this.completedEvent.Set();
return;
}
...
}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
_UploadNextFile();
this.completedEvent.Wait();
operationState.ThrowIfCancelled(); // crash
...
}
As you can see, I marked the line where the crash occurs. What exactly happens is that when execution hits that line (I put a break point right over it, so I know this is the exact line), Visual Studio 2010 freezes for about 15 seconds, and then the next thing I see is the source code of AsyncOperationState.ThrowIfCancelled():
public void ThrowIfCancelled()
{
if(IsCancellationRequested)
{
throw new AsyncOperationCancelException();
}
} // this is the line the debugger highlights: "An exception of type AsyncOperationCancelException' occured in Shd.dll but was unhandled by user code."
I tried putting breakpoints to where the exception should have been caught, but the execution never reaches that catch {} block.
The other weird this is that at the end it also writes the following: "Function evaluation disabled because a previous function evaluation timed out." I Googled this problem, and tried everything that was suggested (disabled implicit property evaluation, removed all breakpoints), but nothing helped so far.
Here are two screenshots that illustrate the problem:
http://dl.dropbox.com/u/17147594/vsd1.png
http://dl.dropbox.com/u/17147594/vsd2.png
I'm using .NET 4.0. Any help would be very much appreciated.
When the Visual Studio debugger is attached to an application, it gets notified whenever an exception is thrown, before the running code gets the chance to handle it. This is called a first-chance exception, and VS can be configured to break execution when a certain exception type is thrown.
You can specify debugger behavior for each exception type separately using the Exceptions window (Debug menu). By default, all exceptions have the "User-unhandled" checkbox checked, meaning that only unhandled exceptions will break execution. Setting the "Thrown" checkbox for a certain exception type forces VS to break execution even if the exception will be handled, but only for that exception type (not for derived types). If a handler exists, once you resume execution (by pressing F5), the exception will be caught normally.
I would guess that your custom exception was added to the list of exceptions in the Exceptions window (which you can check by using the Find button inside the window).
[Edit]
According to my tests, it also happens when DynamicInvoke is used in .NET 4, regardless of the Exceptions window setting. Yesterday I was using VS2008 and I couldn't reproduce it, but it does seem like odd behavior now.
This is the test I tried (sorry for the brief formatting, but it's fairly simple):
Action<int> a = i => { throw new ArgumentException(); };
// When the following code is executed, VS2010 debugger
// will break on the `ArgumentException` above
// but ONLY if the target is .NET 4 (3.5 and lower don't break)
try { a.DynamicInvoke(5); }
catch (Exception ex)
{ }
// this doesn't break
try { a.Invoke(5); }
catch (Exception ex)
{ }
// neither does this
try { a(5); }
catch (Exception ex)
{ }
My only guess is that exception handling done inside InvokeMethodFast (which is an InternalCall method) has somehow changed. DynamicInvoke code has changed between versions 4 and prior, but there is nothing which would indicate why VS2010 debugger is unable to see that there is an exception handler inside that method call.
“a function evaluation has timed out”
You don't have a real problem, this is a debugger artifact. It is triggered by the way the debugger evaluates watch expressions. When you start a .NET program with the debugger attached, the program will have a dedicated thread, solely for use by the debugger. Whenever the debugger needs to evaluate a watch expression, it uses that thread to execute the expression code. The result is then displayed in the watch window.
Which works very well and gives the debugger a lot of capabilities. Including calling a method in your program when a breakpoint is active. Rather necessary, a lot of object values you'd be interested in are exposed as properties. Which are implemented as methods in the generated code.
That debugger thread can however cause trouble. An obvious case is where you try to evaluate a property that takes a lock. If you break execution at a stage where that lock is owned by another thread then the debugger thread is going to hit a brick wall. It trundles for a while, notices that the debugger thread isn't completing, then gives up and displays "a function evaluation has timed out" as the watch value. It also remembers that it failed, any watches you try later will produce "Function evaluation disabled because a previous function evaluation timed out". Necessarily so, the debugger thread is still stuck in a rut.
Similar kind of problem in your code. The probable scenario there is that the thread you need to get the operation completed got suspended by the debugger break. The only decent advice to give here is to be careful with your watch expressions.
If your try catch logic is running on a different thread than the code that actually throws the exception, then the catch block will never execute.
Consider the following sample:
class Program
{
static void Main(string[] args)
{
try
{
Thread thread = new Thread((s) =>
{
throw new Exception("Blah");
});
thread.Start();
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex);
}
Console.ReadKey();
}
}
The catch block of course does not execute since the exception was thrown on a different thread.
I'm suspecting that you could be experiencing something similar. If you want your catch block to execute, it must be on the same thread that the error is being thrown on.
Good luck!
I'm using exceptions to validate a control's input in Silverlight 4. When I throw an invalid input exception, VS 2010 displays the popup and stops the program. I ignore this and resume the program, and everything continues fine (since the exception is used to signal a validation error.) Is there a way to mark that one exception as ignored?
I'm following this tutorial.
Debug -> Exceptions -> Uncheck
Menu, Debugger, Exceptions...
In that dialog, you can remove the checkmark in the 'thrown' column for one exception, of for a whole namespace. You can add your own. etc.etc.
I got [System.Diagnostics.DebuggerHidden()] to work if I also selected
Debug > Options > Debugging > General > Enable Just My Code (Managed only).
I access the Excel object model a lot, and I really like to be able to run the debugger and catching all exceptions, since my code normally is exception less. However, the Excel API throws a lot of exceptions.
// [System.Diagnostics.DebuggerNonUserCode()] works too
[System.Diagnostics.DebuggerHidden()]
private static Excel.Range TrySpecialCells(Excel.Worksheet sheet, Excel.XlCellType cellType)
{
try
{
return sheet.Cells.SpecialCells(cellType);
}
catch (TargetInvocationException)
{
return null;
}
catch (COMException)
{
return null;
}
}
When you run Visual Studio in debug mode, there are Exception Setting on the bottom tool bar. Once you click it, there are all type exceptions. Uncheck exceptions that you want. For the Custom exception you made for this project, they are located in Common Language Runtime Exceptions, at very bottom. Hope this helpful.
You can disable some throw block by surrounding in the block
#if !DEBUG
throw new Exception();
/// this code will be excepted in the debug mode but will be run in the release
#endif
Putting this above the property that throws the exception seems like it should work but apparently doesn't:
[System.Diagnostics.DebuggerHidden()]:
private String name;
[System.Diagnostics.DebuggerHidden()]
public String Name
{
get
{
return name;
}
set
{
if (String.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Please enter a name.");
}
}
}
From Visual Studio 2015 onward there is an Exception Settings window for this.
Debug > Windows > Exception Settings