Why is this SocketException not caught by a generic catch routine? - c#

Our company provides a network component (DLL) for a GUI application.
It uses a Timer that checks for disconnections. If it wants to reconnect, it calls:
internal void timClock_TimerCallback(object state)
{
lock (someLock)
{
// ...
try
{
DoConnect();
}
catch (Exception e)
{
// Log e.Message omitted
// Raise event with e as parameter
ErrorEvent(this, new ErrorEventArgs(e));
DoDisconnect();
}
// ...
}
}
So the problem is, inside of the DoConnect() routine a SocketException is thrown (and not caught). I would assume, that the catch (Exception e) should catch ALL exceptions but somehow the SocketException was not caught and shows up to the GUI application.
protected void DoConnect()
{
//
client = new TcpClient();
client.NoDelay = true;
// In the following call the SocketException is thrown
client.Connect(endPoint.Address.ToString(), endPoint.Port);
// ... (login stuff)
}
The doc confirmed that SocketException extends Exception.
The stacktrace that showed up is:
TcpClient.Connect() -> DoConnect() -> timClock_TimerCallback
So the exception is not thrown outside the try/catch block.
Any ideas why it doesn't work?

If ErrorEvent really raises another exception (per the comment), then DoDisconnect() is never executed.
Otherwise, the exception you see might be coming form DoDisconnect()

I wrote a little program and was unable to reproduce, a SocketException was caught inside a TimerCallback just fine.
So I suggest you re-think your analysis, the problem may not be what you think it is. A few suggestions:
run it outside the Timer. T|hat takes the threading out of the loop.
run it in the debugger. Where does the exception really occur?
step through the exception handling. Is ErrorEvent doing what it should?

Could you post the DoConnect() code?
Also things to try:
Can you catch it in the DoConnect()?
Try catching the specific exception instead of just the generic.
How does it react if you use debug mode?

Your timClock_TimerCallback isn't called in the same thread as the catch-statement wants to catch an exception. You should catch the exception inside timClock_TimerCallback and then call a method which invokes itself and then rethrow the exception in the right thread.
Not sure this will work, but you could give it a try.

Related

C# - Infinite Loop at Exception Throwing?

I have the following code:
protected void ExecuteInTransaction(Action action)
{
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
try
{
action.Invoke();
transaction.Commit();
}
catch(Exception)
{
transaction.Rollback();
throw;
}
}
}
While testing this class, I managed to throw an exception in order to test the catch branch.
As I'm in Debug mode, I continue the execution of this throwing, to see how the calling class handles it, but the exception is never thrown by the method, instead, it's like the exception is constantly being thrown and caught, thrown and caught all over again, never exiting the function.
In Release mode, the application freezes and stops working:
Does anybody know why this is happening, and how can I avoid it?
Thanks in advance!
There is no infinite loop.
Visual Studio just stops at the place where the uncaught exception would abort the program.
Trying to continue does nothing because there is nothing further to execute (VS just displays the same message again to remind you of that).
If you had a try/catch handler in some calling function, you would be able to debug into there.
(But if that catch handler rethrows again, VS would stop there, too.)
Please note that SQLiteTransaction automatically handles rolling back when an open transaction is disposed; it is designed so that your code can be simpler:
protected void ExecuteInTransaction(Action action)
{
using (var transaction = connection.BeginTransaction())
{
action.Invoke();
transaction.Commit();
}
}
Are you sure there's a catch up the stack that can handle this error? The dialog you showed is what you see when an Exception goes unhandled off the top of your program's Main method. The debugger message actually tells you that it was unhandled, so there is no next statement to step to.
Does anybody know why this is happening, and how can I avoid it?
Its hard to say without seeing your call stack.
In general there are 3 possible options:
The exception is being caught higher up the stack.
There's a kernal mode system call somewhere in your call stack and the exception gets swallowed. This only happens when running a 32 bit application on 64 bit windows. The most notable example being an exception thrown in the OnLoad() method of a Form. See VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows for more info.
The exception is being thrown on a ThreadPool thread and not being propagated back to the main thread.
Take the throw; code out of the catch block. If you want to know when the code goes into the catch block then use a breakpoint or Debug.WriteLine().
The catch block of a try/catch doesn't not catch exceptions thrown in itself. So the throw; code is creating an unhandled exception. If you want to test the code that's in the catch block then add the throw; code to the end of the try block.
EDIT:
I didn't realize OP wanted the exception to propogate up the chain. He mentioned nothing about the exception being propagated up the chain and his code shows no support for an exception that propagates up since he doesn't show the code that calls this ExecuteInTransaction(Action) method. A catch block can rethrow the exception that it catches. I agree with that. However the code catch(Exception){ throw; } will not re-enter the same catch block. If it would that would create an infinite loop and that's not what happens. If there is a try/catch block surrounding this then the outer catch block will catch the rethrown exception however his code only includes a single catch block. Therefore when it tries to rethrow the exception there is nothing to catch it and the application breaks.
Try something like this:
private void Main()
{
// Instantiate action variable. I know this wouldn't work, but it's just for show.
Action myAction;
try
{
ExecuteInTransaction(myAction);
}
catch(Exception ex)
{
Debug.WriteLine("Error happened and transaction rolled back. " + ex.Message);
}
}
protected void ExecuteInTransaction(Action action)
{
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
try
{
action.Invoke();
transaction.Commit();
}
catch(Exception ex)
{
transaction.Rollback();
throw ex;
}
}
}

How to quit application in AppDomain.CurrentDomain.UnhandledException handler and still ensure that finally{} blocks execute?

I wish to prevent "application has stopped working" popup from appearing whenever an exception occurs. One way to do this is obviously calling Environment.Exit(1) in a global exception handler, i.e. AppDomain.CurrentDomain.UnhandledException like this:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception exc = (Exception)e.ExceptionObject;
Console.Error.WriteLine("Exception:\n{0}", exc.Message);
Console.Error.WriteLine("Stack trace:\n{0}", exc.StackTrace);
Environment.Exit(1); // quit silently on exception, don't show the popup
}
However, the above code results in finally blocks not executing due to the order of execution. A simple example of such behavior:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
try
{
Console.WriteLine("try block");
throw new Exception("Somebody set us up the bomb.");
}
catch
{
Console.Error.WriteLine("catch block");
throw;
}
finally
{
Console.WriteLine("finally block");
}
Environment.Exit(1) in the exception handler results in this output (notice no finally block) before application quits:
try block
catch block
Exception:
Somebody set us up the bomb.
Stack trace:
at ...
This can cause serious problems when it is critical that finally block executes, e.g. when cleaning up temp files created inside try.
Is there a simple way around all this? That is, keep global exception handler, customize exception output etc. inside it and and then exit gracefully, but still get finally blocks to execute. I find it weird that this problem has not been mentioned in questions like this.
You are not going to get this. Environment.Exit() ensures that finalizers still run, that could be the fallback. But not for cleaning up temporary files, use the operating system support for that and use the FileOptions.DeleteOnClose option.
In general you should never rely on a hard requirement for cleanup, nothing is getting cleaned-up when the CLR bombs with SOE or FEEE, the user terminates you app from Task Manager, hard-reboots the machine or the power goes off.

C# Scope of exception handling

What is the scope of exception handling in C#. I am currently reviewing some code from another programmer on my team and he has a function laid out somewhat like this:
private void function1() {
try {
function2();
}
catch (Exception ex) {
EmailException(ex.message());
}}
private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
}}
The bulk of the processing code is in function2. However his reporting handling is in function1. Will an exception in function2 kick back to the function1 handler that sends the report?
Edit:
Thanks for your responses, they all were very helpful!
Assuming // Handle it here does not rethrow the exception, function1 will never see the original exception.
It is possible function2 will raise a new issue in its catch though, much like it's possible EmailException could err in function1.
Only if
a) function2 re-throws the original exception with throw or a new exception with throw new ...
b) an unexpected exception occurs inside function2's catch block or after it (which actually in this case is impossible since the catch block is the last thing that happens in function2).
No, an exception propagates only until it is caught.
However, you can re-throw the exception at the end of the catch in function2, leading to the desired behaviour:
private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
throw; // <- Re-throw the exception.
// Note this is different from `throw ex;`
}
}
Will an exception in function2 kick back to the function1 handler that sends the report?
No unless
An exception occurs outside of function2's try block
An exception occurs inside the function2 exception block
An exception is thrown e.g. trow or trow ex from function2's exception block
An exception is raised in function2's try block that is automatically retrown like ThreadAbortException
In .net, when an exception occurs, the system will search through the nested try blocks on the stack to determine if there is a catch block that can catch the exception. This occurs before any finally blocks run. If there isn't any block that can catch the exception, the system will invoke an "unhandled exception" handler without running any finally blocks.
If the system that does determine that there is a block that can catch the exception, it will start unwinding the stack and run finally blocks associated with inner try blocks until either it has unwound the stack all the way to the catch block it found, or an exception gets thrown in the execution of a finally block. In the latter situation, the previous exception will be abandoned and not processed further; exception handling will start afresh with the newly-thrown exception.
Although there is a semantic difference between wanting to catch an exception, versus merely wanting to act upon it (but let it be regarded as uncaught), there is no clean way to express that distinction in C#; code which catches an exception is expected to resolve it. The best one can do in C# is use a catch (indicating to the system's exception-processing logic to think one is going to catch the exception) and then use a throw, to indicate one doesn't want to resolve it after all (this will occur after inner "finally" blocks have run). In some other languages such as vb.net, it is possible to act upon exceptions, without catching them, before finally blocks run. While there aren't a huge number of cases where a catch and throw is different from capturing an exception without catching it, there are few cases where the distinction matters. If one is using C# and one wishes to avoid being hostile to surrounding code which might want to capture exceptions from inner code before finalizer blocks run, the best approach is probably to write an exception-handling wrapper method written in vb (or have someone else do it), compile it to a DLL, and then use lambdas to feed such a function methods for it to invoke within a suitable try/filter/catch/finally block.

is this exception handling code valid

Will both catch blocks be hit?
try
{
DoSomething();
}
catch (AuthenticationException e)
{
throw;
}
catch (Exception e)
{
throw new AuthenticationException("Hello ");
}
It's valid (in that it will compile, build and run), but it's not good practice.
Catching the general exception only to rethrow a specific exception will cause problems. If nothing else you are destroying the original exception call stack.
In response to your edit, both catch blocks won't be hit.
If AuthenticationException is raised the first block will be executed, for any other exception the second block will be executed.
Only one exception block will be hit. And they go in order, so if DoSomething() throws an AuthenticationException, the first catch block will run.
That said, I'd probably not use try/catches here at all if all you're doing is rethrowing the exceptions. This is not a good practice. At the very least, make sure you add the original exception in your second catch as the InnerException of the AuthenticationException you're creating:
catch(Exception e)
{
throw new AuthenticationException(e.Message, e);
}
This code will throw an AutheniticationException if DoSomething throws anything. It will be the same exception if DoSomething throws AuthenticationException, or a new exception in any other case.
A side note - its not really good practise:
You loose all details of an exception which is not AuthenticationException
Why would you throw an AuthenticationException here, if the underlying code thinks there is something else wrong? A code smell for me.
Yes if you have different kinds of exceptions. (2 exceptions)
No if you wish that the first block will arrive in the second. (1 exception)
No. Both catch blocks will not be hit.
If DoSomething throws an AuthenticationException, then it will be caught and rethrown.
If DoSomething throws any other exception, a new AuthenticationException will be thrown with the message "Hello".
If DoSomething() throws an AuthenticationException then
catch (AuthenticationException e)
will be used. For all other types of exceptions,
catch (Exception e)
But you shouldn't throw a new AuthenticationException inside the second catch.
The second block will not catch the rethrown exception from the first block.
One benefit I can see for catching and rethrowing an exception would be to convey the message, "The requested operation did not succeed, but the system state is essentially as it was before the operation was attempted." While catching all exceptions in an inner routine and hoping that none of them represent a problem which should cause the main program to terminate is somewhat icky, I'm not sure what alternative design is better. One could litter the code with:
If Not Integer.TryParse(inputString, inputVar) Then
Throw New MyApp.FileLoadException("Whatever")
EndIf
but it really seems more natural to just use Integer.Parse and catch any exception that occurs. Catching and recasting general exceptions within a small domain where their expected causes are known is far less evil than swallowing general exceptions at a higher level.

WCF/C# Unable to catch EndpointNotFoundException

I have created a WCF service and client and it all works until it comes to catching errors. Specifically I am trying to catch the EndpointNotFoundException for when the server happens not to be there for whatever reason. I have tried a simple try/catch block to catch the specific error and the communication exception it derives from, and I've tried catching just Exception. None of these succeed in catching the exception, however I do get
A first chance exception of type
'System.ServiceModel.EndpointNotFoundException'
occurred in System.ServiceModel.dll
in the output window when the client tries to open the service. Any ideas as to what I'm doing wrong?
I was able to replicate your issue and got interested (since I needed the same). I even researched a way to handle \ catch first chance exceptions but unfortunately it is not possible (for managed code) for .net framework 3.5 and below.
On my case I always get a System.ServiceModel.CommunicationObjectFaultedException whenever something gets wrong on the service or whenever I access a down service. It turns out that c#'s using statement is the cause since behind the scene, the using statement always closes the service client instance even if an exception was already encountered (it doesn't jump to catch statement directly).
What happens is that the original exception System.ServiceModel.EndpointNotFoundException will be replaced by the new exception System.ServiceModel.CommunicationObjectFaultedException whenever the using tries to close the service client instance.
The solution i've made is to not use the using statement so that whenever an exception is encountered inside the try block it will instantly throw the exception to the catch blocks.
Try to code something like:
DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient();
try
{
svc.GetChart(0);
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here
}
catch (Exception ex)
{
//general exception handler
}
finally
{
if (!svc.State.Equals(System.ServiceModel.CommunicationState.Faulted) && svc.State.Equals(System.ServiceModel.CommunicationState.Opened))
svc.Close();
}
Instead of:
try
{
using (DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient())
{
svc.GetChart(0);
}
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here (I was never able to catch this type of exception using the using statement block)
}
catch (Exception ex)
{
//general exception handler
}
And you'll be able to catch the right exception then.
Take a look at this post for details on this possible solution. The code shows use of a generate proxy but is valid on ChannelFactory and others as well.
Typical here-be-dragons pattern
using (WCFServiceClient c = new WCFServiceClient())
{
try
{
c.HelloWorld();
}
catch (Exception ex)
{
// You don't know it yet but your mellow has just been harshed.
// If you handle this exception and fall through you will still be cheerfully greeted with
// an unhandled CommunicationObjectFaultedException when 'using' tries to .Close() the client.
// If you throw or re-throw from here you will never see that exception, it is gone forever.
// buh bye.
// All you will get is an unhandled CommunicationObjectFaultedException
}
} // <-- here is where the CommunicationObjectFaultedException is thrown
Proper pattern:
using (WCFServiceClient client = new WCFServiceClient())
{
try
{
client.ThrowException();
}
catch (Exception ex)
{
// acknowledge the Faulted state and allow transition to Closed
client.Abort();
// handle the exception or rethrow, makes no nevermind to me, my
// yob is done ;-D
}
}
Or, as expressed in your question without a using statement,
WCFServiceClient c = new WCFServiceClient();
try
{
c.HelloWorld();
}
catch
{
// acknowledge the Faulted state and allow transition to Closed
c.Abort();
// handle or throw
throw;
}
finally
{
c.Close();
}
This may be a reporting issue for the debugger, rather than not actually catching the exception. this post gives some tips on resolving it, if that is the case... Why is .NET exception not caught by try/catch block?
What is a First Chance Exception?
First chance exception messages most
often do not mean there is a problem
in the code. For applications /
components which handle exceptions
gracefully, first chance exception
messages let the developer know that
an exceptional situation was
encountered and was handled.
Place a try catch block in the CompletedMethod.
An Example:
...
geocodeService.ReverseGeocodeCompleted += ReverseGeocodeCompleted(se, ev);
geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
}
private void ReverseGeocodeCompleted(object sender, ReverseGeocodeCompletedEventArgs e)
{
try
{
// something went wrong ...
var address = e.Result.Results[0].Address;
}
catch (Exception)
{ // Catch Exception
Debug.WriteLine("NO INTERNET CONNECTION");
}

Categories