I set my Visual Studio Exception Settings to Break When 'Common Language Runtime Exceptions' are thrown.
I have numerous routines where I catch exceptions, handle them and continue. When I'm debugging my program, I trust that these exceptions have been correctly handled and do not want the debugger to stop on them.
How can I prevent the debugger from stopping on handled exceptions?
(Note, I want to break on all other CLR exceptions)
I thought DebuggerStepThrough would do the trick. However it doesn't. The following code stops on 'Method1();'
using System;
namespace ConsoleApp8
{
class Program
{
static void Main(string[] args)
{
Method1();
}
[System.Diagnostics.DebuggerStepThrough]
static void Method1()
{
try
{
throw new InvalidOperationException();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
-- Edit --
Kirk - I only throw exceptions in exceptional situations. I work with Visual Studio Tools for Office. This MS library often throws exceptions that can be handled and ignored.
I would like to handle certain exceptions thrown by another library but prevent the VS2017 debugger from stopping when these errors occur.
To be clear, these exceptions are usually COM Exceptions. I don't want the debugger to ignore ALL COM Exceptions. I only want the debugger to ignore COM Exceptions that I have caught and handled.
Is this possible?
The debugger can break execution at the point where an exception is thrown, so you may examine the exception before a handler is invoked. In the Exception Settings window (Debug > Windows > Exception Settings), expand the node for a category of exceptions, such as Common Language Runtime Exceptions. There you can change the behaviour.
Related
My code calls a WCF service that is current not running. So we should expect the EndPointNotFoundException. The using statement tries to Close() the faulted connection which causes a CommunicationObjectFaultedException which is excepted. This exception is caught in a try catch block surrounding the using block:
class Program
{
static void Main()
{
try
{
using (ChannelFactory<IDummyService> unexistingSvc = new ChannelFactory<IDummyService>(new NetNamedPipeBinding(), "net.pipe://localhost/UnexistingService-" + Guid.NewGuid().ToString()))
{
using (IClientChannel chan = (unexistingSvc.CreateChannel() as IClientChannel))
{
(chan as IDummyService)?.Echo("Hello");
}
}
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("Expected");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Expected: caused by closing channel that has thrown EndPointNotFoundException");
}
}
}
Note the service EndPoint uses a fresh Guid so it will never have a service listening.
IDummyService is:
[ServiceContract]
interface IDummyService
{
[OperationContract]
string Echo(string e);
}
This causes the Visual Studio debugger (Visual Studio Professional 2017 15.4.1) to break with an "Exception Unhandled" popup:
The exception on which Visual Studio breaks is System.ServiceModel.CommunicationObjectFaultedException which is caught in the code.
Stepping to continue execution shows that catch(CommunicationObjectFaultedException ex) is reached. Using LinqPad to run the demo also shows that the exception is caught as expected.
I also tried explicitly (double) closing the channel instead of using the using-block:
class Program
{
static void Main()
{
try
{
using (ChannelFactory<IDummyService> unexistingSvc = new ChannelFactory<IDummyService>(new NetNamedPipeBinding(), "net.pipe://localhost/UnexistingService-" + Guid.NewGuid().ToString()))
{
IDummyService chan = null;
try
{
chan = unexistingSvc.CreateChannel();
chan.Echo("Hello");
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine($"Expected: {ex.Message}");
}
finally
{
try
{
(chan as IClientChannel)?.Close();
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine($"Caused by Close: {ex.Message}");
}
}
}
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("Expected");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Expected: caused by closing channel that has thrown EndPointNotFoundException");
}
}
}
This still causes the debugger to break on the Close statement.
My Exception Settings has System.ServiceModel.CommunicationObjectFaultedException unchecked. (When it is checked Visual studio breaks as expected and with the "Exception Thrown" dialog instead of the "Exception Unhandled" dialog).
When I enable "Options"\"Debugging"\"General"\"Enable Just My Code" the debugger does not break. However, I have async methods where the exception should leave my code and I later catch the exception when awaiting the Task. For these methods I need "Enable Just My Code" unchecked; see Stop visual studio from breaking on exception in Tasks.
With "Using the New Exception Helper" disabled (as suggested by Jack Zhai-MSFT) Visual Studio still breaks and it shows
The dialog provides some additional information:
The exception is not caught before it crosses a managed/native boundary.
I suspect that the using block probably introduces this managed/native boundary.
What causes the debugger to break by mistake and how to make the debugger not break neither or handled CommunicationObjectFaultedExceptions nor on later handler async exceptions?
The new Exception feature was in VS2017, we could disable debugging option "Use the New Exception Helper" under TOOLS->OPTION->Debugging->General which could provide you the old Exception messages, you could visit it.
The old Exception Message shows that the Exception crosses a managed/native boundary:
Check "Break when Exceptions cross AppDomain or managed/native boundaries" under TOOLS->OPTION->Debugging->General. Disable "Break when Exceptions cross AppDomain or managed/native boundaries" to avoid Visual Studio breaking on the OP's situation (be careful though since this also disables breaking on other situations where an exception crosses an AppDomain or managed/native boundary).
Close()-ing a Faulted IClientChannel causes a CommunicationObjectFaultedException:
public void Close(TimeSpan timeout)
{
...
switch (originalState)
{
case CommunicationState.Created:
case CommunicationState.Opening:
case CommunicationState.Faulted:
this.Abort();
if (originalState == CommunicationState.Faulted)
{
throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
}
break;
...
}
...
}
-- (See CommunicationObject.Close(TimeSpan) line #299 in the .NET framework 4.7 reference source).
The using-block is translated to try { ... } finally { Dispose(); } and Dispose() calls Close() when the block is left. The proxy returned by CreateChannel() is implemented via RealProxy (src) and RemotingServices.CreateTransparentProxy() these proxy combine managed and unmanaged code, which might cause the exception crossing the boundary.
The combination of settings (in TOOLS->OPTIONS->Debugger->General):
☑ Break when Exceptions cross AppDomain or managed/native boundaries
☐ Enable Just My Code
Causes Visual Studio to break showing either: the new non-modal exception popup "Exception Unhandled":
or the modal dialog:
The CommunicationObjectFaultedException starts in 'Not My Code'; it crosses an managed/unmanaged or AppDomain boundary while still being in 'Not My Code'; and finally enters 'My Code' where it is handled by the catch-block (but Visual Studio has already halted the excuting at this point).
Since the exception starts in 'Not My Code' and remains there when crossing the boundary, selecting the option "Enable Just My Code" causes Visual studio to not break on the exception even when it crosses the AppDomain or managed/unmanaged boundary.
Deselecting "break when exceptions cross AppDomain or managed/native boundaries" also causes Visual Studio to not break on the exception.
This gives two solutions/workarounds
Choose a different combination of "Break when Exceptions cross AppDomain or managed/native boundaries" and "Enable Just My Code"
Do not use a using-block for the IClientChannel and check IClientChannel.State before Close()-ing. As is done in What is the best workaround for the WCF client `using` block issue?
Normally I want the debugger to break on ArgumentOutOfRangeException.
But within my try catch(ArgumentOutOfRangeException) that exception is already handled and so I want the debugger to not break.
I tried the DebuggerStepThrough attribute, but it still breaks.
You can do this by setting the debugger to break on user unhandled exceptions.
Go to Debug -> Exceptions, Common Language Runtime Exceptions, de-tick (uncheck) the Thrown box. Of course you can get very precise with what you want to break on by drilling down into that list. Be aware that this setting takes effect across the whole solution, you can't set it per class or method. If you do want to be more selective per method, then consider using compile directives to not include that bit of code during debug time.
As for the DebuggerStepThrough attribute, that is to prevent breaking on break points, nothing to do with breaking on exceptions.
You should check your visual studio isn't set to break on all exceptions
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.
Microsoft Visual Studio Help
There is a way. First disable debugging code that is not yours. Go to Tools > Options > Debugging > General > select "Enable Just My Code (Managed only)". Now tell the debugger that this one function is not part of your code with DebuggerNonUserCodeAttribute:
[System.Diagnostics.DebuggerNonUserCode()]
private void FunctionThatCatchesThrownException()
{
try
{
throw new ArgumentOutOfRangeException();
}
catch (ArgumentOutOfRangeException ex)
{
//...
}
}
If an exception (some other than ArgumentOutOfRangeException) gets out of the function debugger will catch it as usual, but the location of interception will be where the function is called.
I have a class Dispatcher with a method Send as follows:
public class Dispatcher : IDispatcher {
public void Send(Order order) {
Type type = typeof(IOrderHandler<>).MakeGenericType(order.GetType());
IOrderHandler handler = (IOrderHandler)ObjectFactory.GetInstance(type);
try {
handler.Handle(order);
} catch (Exception exception) {
ILogger logger = ObjectFactory.GetInstance<ILogger>();
logger.Send(exception);
}
}
} // Send
I am handling orders and catching exceptions ...
When I am debugging I would like to still fire the exception.
How can I do this?
Thank You,
Miguel
Just add this line to your catch block:
if (System.Diagnostics.Debugger.IsAttached) throw;
You can add the following in your catch block:
#if DEBUG
throw;
#endif
So your code would look like:
try
{
handler.Handle(order);
}
catch (Exception exception)
{
ILogger logger = ObjectFactory.GetInstance<ILogger>();
logger.Send(exception);
#if DEBUG
throw;
#endif
}
If you want the exception notification in IDE during debugging in Release configuration, then use #Hans Passant's answer, because that will let you know about the exception for both Release and Debug configuration.
Well, based on the fact that you'd like the exception to still be thrown, but only when debugging, you could do this:
Open the Debug menu and choose Exceptions.
When the dialog loads, tick the check box next to Common Language Runtime Exceptions under the Thrown heading.
This will cause you to get a first chance exception. What that means is you'll be notified by the IDE, when debugging, and you'll get a chance to handle it before processing continues. This will actually let you see it before it even gets logged.
What's more, you can actually unselect exceptions you don't want with this approach because they are broken down by exception type underneath the Common Language Runtime Exceptions grouping.
More detail...
Go to Debug > Exception and check the CLR exceptions for "thrown", this will take you right there. alternatively place a breakpoint on the catch block.
I have a function in C# code where a NullReferenceException is thrown periodically (expected behavior), but caught. Is there a way I can tell the Visual Studio debugger to not break on this exception for this particular section of my code?
EDIT I need to break on this exception elsewhere in my code, but not in the same function.
If I understand correctly and what you're trying to do is debug some NullReferenceException(s) but want to temporarily ignore others while debugging, you might be able to do this by marking functions that you want the debugger to ignore with the DebuggerNonUserCode attribute.
[DebuggerNonUserCode]
private void MyMethod()
{
// NullReferenceException exceptions caught in this method will
// not cause the Debugger to stop here..
}
NOTE that this will only work if the exceptions are caught in said methods. It's just that they won't cause the debugger to break if you have the debugger set to always break on NullReferenceException exceptions. And that this only works on methods, and not arbitrary sections of code inside of a method..
Assuming the exception does not bubble up to the caller, this can be achieved with DebuggerHiddenAttribute.
From the remarks
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.
[DebuggerHidden]
private static void M()
{
try
{
throw new NullReferenceException();
}
catch (Exception)
{
//log or do something useful so as not to swallow.
}
}
You can do this, but it does effect all exceptions in the solution.
Debug -> Exceptions -> Find... "Null Ref", de-tick Thrown.
There has been discussion here before about the correct way to rethrow an exception. This question, instead, is about how to get useful behavior from Visual Studio when using rethrow.
Consider this code:
static void foo() {
throw new Exception("boo!");
}
static void Main(string[] args) {
try {
foo();
} catch (Exception x) {
// do some stuff
throw;
}
}
The exception that comes out has the correct stack trace, showing foo() as the source of the exception. However, the GUI Call Stack window only shows Main, whereas I was expecting it to show the exception's call stack, all the way to foo.
When there is no rethrow, I can use the GUI to very quickly navigate the call stack to see what call caused the exception and how we got there.
With the rethrow I'd like to be able to do the same thing. Instead, the call stack that the GUI shows is of no use to me. I have to copy the exception details to the clipboard, paste it to Notepad, and then manually navigate to whichever function of the call stack I'm interested in.
By the way, I get the same behavior if I add [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] or if I change the catch to just catch (Exception).
My question is: given that the code I have uses rethrow, can someone suggest a convenient way to navigate the call stack associated with the exception? I'm using Visual Studio 2010.
The debugger breaks at the throw in Main because that exception is unhandled. By default, the debugger will only break on unhandled exceptions. Once you've stopped at Main, the call stack for the original exception from foo is present in the exception, but all of the other context has been lost (e.g. locals, stack/memory state).
It sounds like you want the debugger to break on the throw in foo, so you should tell the debugger to break on first-chance exceptions:
Debug » Exceptions... (Ctrl+Alt+E)
Check "Thrown" for the exception types you care about (in this case, Commange Language Runtime Exceptions)
Click OK
Start debugging
In this case, the debugger will break immediately when foo throws an exception. Now, you can examine the stack, locals, etc., in the context of the original exception. If you continue execution (F5), the debugger will break again on the rethrow in Main.
Taking another approach, if you're running VS2010 Ultimate, you can also use IntelliTrace to "debug backwards" to see parameters, threads, and variables at the time of the exception. See this MSDN article for details. (Full disclosure: I work on a team closely related to IntelliTrace).
If you use ReSharper, you can copy exception stacktrace to clipboard, then choose in the menu: ReSharper > Tools > Browse Stack Trace (Ctrl+E,T). It will show stacktrace with clickable locations, so you'll be able to quickly navigate.
(source: jetbrains.com)
This feature is also very useful while digging through logs from users (if stacktraces of exceptions are logged).
Not that you should re-throw but here's a blog post about how to preserve the stack trace, essentially it boils down to this:
private static void PreserveStackTrace(Exception exception)
{
MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(exception, null);
}
...
catch (Exception ex)
{
// do something
// ...
PreserveStackTrace(ex);
throw;
}
Mike Stall has given a great and simple solution to your problem:
Mark the methods where you rethrow the exception with the attribute [DebuggerNonUserCode]
The IDE will consider this is not your code and will not break the debugger in such place, and instead will look further in the stack, showing the next rethrow or the initial exception place.
(if the next rethrow is also annoying, mark it as [DebuggerNonUserCode] as well, etc...)