It is common knowledge that there is no such thing as software without bugs. There are several bugs out there that are hiding and therefore are not handled at all. We surely don’t want to release a software that will crash ungracefully due to such a case. Fortunately, the .Net framework makes it possible to take care of the exceptions that slipped out of our hands: the un-handled¬† exceptions.

In order to do that, we must handle the AppDomain.CurrentDomain.UnhandledException event in the Main method. This event is fired every time an un-handled exception proceed all the way to the top of our application.  At that point, there is no way to recover.

-
static void Main(string[] args)
 {
     AppDomain.CurrentDomain.UnhandledException +=
         new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
 }

In the implementation of the CurrentDomain_UnhandledException method, we can write to the log, close some open handles and most important – show a pleasant message to the user.

-
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    try
    {
        // Write to the log, close handels, ...
        // Show message box.
    }
    finally
    {
        Application.Exit();
    }
}

I must point out that the UnhandledException event can be triggered not only in the main thread (UI thread) but in all other threads as well. As already mentions, this event will result in the termination of the application. There is a different way to handle exceptions that occurred on the UI thread, use the Application.ThreadException event so that unhandled exception that occurred on the UI thread will not hit the UnhandledException on the AppDomain class.

-
Application.ThreadException +=
  new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

There is a possibility to continue and not abort the application, let the user decide by giving him this option in a dialog box.

-
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs t)
{
   DialogResult result = DialogResult.Cancel;
   try
   {
      result = ShowThreadExceptionDialog(t.Exception);
   }
   catch
   {
      try
      {
         MessageBox.Show("Fatal Error", "Fatal Error",
                    MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
      }
      finally
      {
         Application.Exit();
      }
   }   

   // Exits the program when the user clicks Abort.
   if (result == DialogResult.Abort)
      Application.Exit();
}

So, if our program is made up from one UI thread, use the Application.ThreadException. When in multi threaded or non UI applications, the AppDomain.UnhandledException is a must. I want to emphasis 3 more issues:

  1. Don’t forget to catch exceptions thrown in Main().
  2. ThreadAbortException is a special case – read more about it.
  3. As far as I can tell there is no way to handle all un-handled exceptions in a .NET application that interact with unmanaged code with threads. Identify the spots where the underlying thread could come from unmanaged code and pay attention to exception handling within that code.

Tags :

3 Responses to “Unhandled Exceptions – Handle them”


  1. Michael

    Said on April 15, 2008 :

    Application.Exit assumes that you have a message loop. I suggest you mention the Environment.Exit() and Environment.FailFast();

2 Trackback(s)

  1. Apr 17, 2008: Reflective Perspective - Chris Alcock » The Morning Brew #75
  2. Apr 18, 2008: Weekly Web Nuggets #8 : Code Monkey Labs

Post a Comment