Unhandled Exceptions with AppDomain.CurrentDomain.UnhandledException and Application.ThreadException

I have a strong belief that an application should fail in a way that is graceful and useful for fixing the problem. Because of this i was looking for a way to catch and any exceptions that you may have missed. This gives you the opportunity to log and possibly email you specific information to be able to fix the issue. What i found looked like this.

On start up subscript to the AppDomain.CurrentDomain.UnhandledException

            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                var ex = (Exception)e.ExceptionObject;
                LogHelper.Log(typeof(ICollationManager), ex);
                MessageBox.Show("An unhandled exception has occurred.\nPlease refer to the log file.", "Log File", MessageBoxButtons.OK, MessageBoxIcon.Error);
            };

The problem i found though was some exceptions were not being captured by this. After some digging i found that this event is not really an event handler for all unhandled exceptions, instead it is a last chance event before your application is terminated due to an unhandled event. Sometimes the CLR though can decide that this type of exception does not need to terminate the application hence why it wasn’t triggering this event. It seems like it also depends on what thread the exception was thrown. A scenario we encountered was where we were updating a SQL table when a WinForm’s windows was closing. We were doing this in the closing event but there as an issue with the Linq statement that was throwing an exception. It looked like because this event was triggered by the form that it was treating this exception as one that would not terminate the application which is why the event was not being fired. I did some more digging around found that this is only part of the solution. We also needed to subscribe to the Application.ThreadException

The solution ended up looking like this

            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                var ex = (Exception)e.ExceptionObject;
                LogHelper.Log(typeof(ICollationManager), ex);
                MessageBox.Show("An unhandled exception has occurred.\nPlease refer to the log file.", "Log File", MessageBoxButtons.OK, MessageBoxIcon.Error);
            };

            Application.ThreadException += (s, e) =>
            {
                var ex = e.Exception;
                LogHelper.Log(typeof(ICollationManager), ex);
                MessageBox.Show("An unhandled exception has occurred.\nPlease refer to the log file.", "Log File", MessageBoxButtons.OK, MessageBoxIcon.Error);
            };

Note that Application.ThreadException is for WinForms only, WPF seems to use Application.DispatherUnhandledException and other technologies

Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: