Wordsmyth's Corner

How to Trap All Unhandled Exceptions

There are a variety of application exceptions that can occur in a Visual Studio .NET/C# forms app. To trap the different kinds of unhandled exceptions, you must add three different exception handlers to your application. Usually it's easiest to do this in the Main function in Program.cs

The following example shows how to funnel all the different kinds of unhandled exceptions to a single method: HandleCriticalError. To the best of my knowledge, this will trap all unhandled exceptions.

      [STAThread]
      static void Main()
         {
 
         // Hook up our main exception handlers.  There are three types of exceptions we
         // have to worry about.
         //  * Thread Exceptions: Occurs in the main app thread 
         //  * Unhandled Exceptions: Occurs in the rest of the app domain (excluding the main app thread)
         //    AFTER you've called Application.Run
         //  * Early Exceptions: Occur BEFORE you've called Application.Run
         // The first two have special event handlers.  The third is handled by the surrounding
         // try/catch block below.
         //
 
         try
            {
 
            Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
 
            ... other stuff ...
            }
 
         catch (Exception exception)
            {
            HandleCriticalError(exception);
            }
         }
 
      // METHOD: ThreadExceptionHandler
      //------------------------------------------------------------------------
      /// <summary>
      /// Catcher for all unhandled exceptions from the app's main thread.
      /// </summary>
      /// 
      /// <returns>
      /// None
      /// </returns>
      ///
      /// <!-- PARAMETERS -->
      /// <param name="sender">
      /// Object sending the event.
      /// </param>
      /// 
      /// <param name="args">
      /// Event args, which include the exception class.
      /// </param>
      //------------------------------------------------------------------------
 
      static void ThreadExceptionHandler(object sender, ThreadExceptionEventArgs args)
         {
         HandleCriticalError((Exception)args.Exception);
         }
 
      // METHOD: UnhandledExceptionHandler
      //------------------------------------------------------------------------
      /// <summary>
      /// Catcher for all unhandled exceptions from the App Domain.
      /// </summary>
      /// 
      /// <returns>
      /// None
      /// </returns>
      ///
      /// <!-- PARAMETERS -->
      /// <param name="sender">
      /// Object sending the event.
      /// </param>
      /// 
      /// <param name="args">
      /// Event args, which include the exception class.
      /// </param>
      //------------------------------------------------------------------------
 
      static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
         {
         HandleCriticalError((Exception)args.ExceptionObject);
         }

      // METHOD: HandleCriticalError
      //------------------------------------------------------------------------
      /// <summary>
      /// Registers a critical error with the system.
      /// </summary>
      /// 
      /// <returns>
      /// None
      /// </returns>
      ///
      /// <!-- PARAMETERS -->
      /// <param name="exception">
      /// The exception that caused the error.
      /// </param>
      //------------------------------------------------------------------------
 
      static void HandleCriticalError(Exception exception)
         {
 
         // We're already handling a critical error, so any recursive exceptions
         // are rather redundant.  Just catch them so we don't trigger .NET's
         // built-in  "The app has suffered an error..." handler.  
         try
            {
            // Do error handling here.
            }
         catch
            {
            }
 
         }
      }