views:

288

answers:

2

I recently encountered a behavior that I've never seen before. I cannot quite understand what's going on most likely due to lack of fundamental knowledge with regards to the inner workings Exception Handling - or maybe I am just missing something obvious.

I recently added exception handling to an app as a sort of fallback in case of unhandled exceptions. I am basically handling ThreadException and UnhandledException as shown below:

// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ExceptionHandler.OnUIThreadException);

// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

// Add the event handler for handling non-UI thread exceptions to the event. 
AppDomain.CurrentDomain.UnhandledException +=
    new UnhandledExceptionEventHandler(ExceptionHandler.OnUnhandledException);

// Runs the application.
Application.Run(new ErrorHandlerForm());

Some other piece of code I had in the app was already catching exceptions - and since I didn't have exception handling in place I was just rethrowing the exception to make sure it was not swallowed:

//code in some method of the Program
try
{
   foo.SomeFooCall();
}
catch(Exception ex)
{
  logger.Log(ex.Message);
  // I don't swallow!
  throw;
}

Once I had the exception handling in place (which is also logging) I should've removed that try catch block above - but I forgot to do so and I am experiencing a strange behavior which is the subject of this question.

When and exception is thrown somewhere inside the foo call, it is obviously caught by the code above, logged then thrown again. At this point ExceptionHandling kicks in, does some logging and notification (a simple messagebox) then goes Application.Exit(). What happens next is that the app will go back on the same throw which will trigger error handling whit the same results, and this will go on a number of times till it crashes presumably 'cause the stack trace is full or it somehow detects the infinite loop.

EDIT: The above is in debug mode - if I just run it it'll handle the exception once (show the messagebox, log etc.), then it'll just crash (I am guessing for stack overflow).

I anticipate the answer to this might be trivial (or I may be missing something obvious) - but any pointers/explanations will be highly appreciated.

EDIT: The exception handlers methods take both call down to an OnException method that goes something like:

private void OnUIThreadException(object sender, ThreadExceptionEventArgs e)
{
   OnException(e.Exception);
}

private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
   OnException((Exception)e.ExceptionObject);
}

private void OnException(Exception exception)
{
   MessageBox.Show("Fatal Exception: " + exception.Message);

   logger.Log(LoggingLevel.FATAL, "myLousyApp", exception.Message);

   Application.Exit();
}

I am actually doing smt more than just that - such as asking the user if they want to restart the app and if so restarting it with process id as cmd arg so that when it restarts it'll wait for the old process to exit (it's protected from duplicates instances through a mutex). But for this question this is irrelevant since I am not restarting the app when I experience the behavior described.

EDIT: I created another simple app to reproduce this conditions - I have a simple component that throws exceptions (I am throwing an arbitrary number of exception in a loop), but in all my tests on Application.Exit the app just shuts down nicely and I can't reproduce it. Puzzled with regards to what I should be looking for!

A: 

I suspect that in ExceptionHandler.OnUnhandledException a new exception might be raised which remains unhandled, gets bubbled up to the unhandled exceptions handler, which raises your ExceptionHandler.OnUnhandledException method and so on.. (infinite loop -> stack overflow).

So doublecheck your OnUnhandledException method for thrown errors.

Edit: funny, I try to reproduce your error, but instead of throwing an error again and again, my app. simply exits after the unhandled exception handler method, no matter what happens in there. Were you debugging or running? It might cause a difference.

Webleeuw
I was debugging - if I just run the exception gets handled (notification is shown) and then instead of the app just closing down it crashes (with no message)
JohnIdol
see edit for further details
JohnIdol
+2  A: 

Hard to tell without knowing what the code for the original throw is doing. It is possible that there are outstanding forms events that get processed as part of the app shutdown that ends up re-invoking the original code fragment. It could also be a virtual function on your application class that gets invoked during shutdown.

You should be able to just print the stack trace from your catch handler to figure it out though.

Jeff Kotula