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?
Related
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.
Using using third party library I experience interesting situation. The following code breaks on exception:
var instance = new Class(arg);
But when this line is enclosed in try/catch block, the exception is never caught.
Of course, the visual studio debugger stops on the exception only when the break on given exception type is enabled. When disabled, the exception disappears (at all). The catch block is never executed. Does not matter if catch (Exception exc) {} or catch {} is used. The exception is derived from Exception.
How is this possible?
I suppose this might be common trick or practice to have "debug only" exceptions. The third party library uses code like this:
public class Class
{
public Class(object arg)
{
try
{
...
throw new Exception("message");
...
}
catch
{
// This is just empty. By purpose.
}
finally
{
...
}
}
}
The debugger then stops on the throw statement (if configured to do so), but as the exception is "handled", it does not propagate anywhere else...
I am sure I am doinig something wrong, but when I try this example of the new threading task exception handling I keep getting the exception unhandled by user code. The whole point of the code is to show an example of how to catch errors in tasks.
Link: Task Exception Example
static void Main(string[] args)
{
var task1 = Task.Factory.StartNew(() =>
{
throw new MyCustomException("I'm bad, but not too bad!");
});
try
{
task1.Wait();
}
catch (AggregateException ae)
{
// Assume we know what's going on with this particular exception.
// Rethrow anything else. AggregateException.Handle provides
// another way to express this. See later example.
foreach (var e in ae.InnerExceptions)
{
if (e is MyCustomException)
{
Console.WriteLine(e.Message);
}
else
{
throw;
}
}
}
}
Most likely user error just not sure what (Using Visual Studio 2012);
From the page you cited:
Note
When "Just My Code" is enabled, Visual Studio in some cases will
break on the line that throws the exception and display an error
message that says "exception not handled by user code." This error is
benign. You can press F5 to continue and see the exception-handling
behavior that is demonstrated in these examples. To prevent Visual
Studio from breaking on the first error, just uncheck the "Just My
Code" checkbox under Tools, Options, Debugging, General.
I'm receiving an unhandled exception while debugging, and the program stops executing. The debugger doesn't show me the line so I don't know what to fix.
An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll
Additional information: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
Cannot obtain value of local or argument '<this>' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Threading.Tasks.TaskExceptionHolder
How can I troubleshoot this problem?
I also found this question which is pretty similar.
As the message says, you have a task which threw an unhandled exception.
Turn on Break on All Exceptions (Debug, Exceptions) and rerun the program.
This will show you the original exception when it was thrown in the first place.
(comment appended): In VS2015 (or above). Select Debug > Options > Debugging > General and unselect the "Enable Just My Code" option.
You could handle the exception directly so it would not crash your program (catching the AggregateException). You could also look at the Inner Exception, this will give you a more detailed explanation of what went wrong:
try {
// your code
} catch (AggregateException e) {
}
The accepted answer will work if you can easily reproduce the issue. However, as a matter of best practice, you should be catching any exceptions (and logging) that are executed within a task. Otherwise, your application will crash if anything unexpected occurs within the task.
Task.Factory.StartNew(x=>
throw new Exception("I didn't account for this");
)
However, if we do this, at least the application does not crash.
Task.Factory.StartNew(x=>
try {
throw new Exception("I didn't account for this");
}
catch(Exception ex) {
//Log ex
}
)
In my case I ran on this problem while using Edge.js — all the problem was a JavaScript syntax error inside a C# Edge.js function definition.
I am running this test case using NUNIT and attaching the NUNIT to the Visual studio debugger (Debug ---> Attach to Process ---> Select nunit.exe).
I was expecting the statement "throw new Exception("Exception 1 occured!");"to move the control into the catch block but
the control does not jump to the "catch" but instead jumps to method2().
When I just run the nunit test case without attaching nunit.exe to the Visual Studio debugger the code behaves normally.
public void test()
{
try
{
method1();
if (condition1)
{
throw new Exception("Exception 1 occured!");
}
method2();
if (condition2)
{
throw new Exception("Exception 2 occured!");
}
method3();
if (condition3)
{
throw new Exception("Exception 3 occured!");
}
}
catch (Exception Ex) <---- Exceptions thrown above are caught here
{
logMessage(E.Message);
throw;
}
}
Visual Studio is probably set to break on all Exceptions instead of just uncaught Exceptions. So it stops when it detects that you threw the Exception. In certain cases, rather than appearing to break on the line that throws the exception, Visual Studio highlights the next line of code which was about to run.
If you continue to step through the code, you should see it go to the catch block next.