What Gives? Unhandled Exceptions

7 בדצמבר 2008

2 תגובות

Are you tired of these errors:

image

image

image

I know I am!!! So, what can we do about it? Simple, lets handle our unhandled exceptions.

Exceptions can be raise from a different layers or tiers, however we always want to control them. Sometimes we want to ignore them and let them bubble, on other occasions we want to handle them and re-throw them and on other cases we want to handle them and swallow the exception. In this post I will talk about the last option.

Usually when we are building a desktop application we will want to "swallow" any unhandled exceptions…but not just "swallow" them, but handle them in the most proper manner. This can be achieve by several ways:

  • Write the exception to a log.
  • Notify.
  • Try to recover from the exception (if possible).
  • Show the user a message that an exception occurred and ask him to take action, where action can be either "continue" or "close".

So, how can we handle those unhandled exceptions?

There are two events we want to hook up to:

  • ThreadException event which occurred when a thread causes an unhandled exception.
  • AppDomain.CurrentDomain.UnhandledException event which occurred when exception is not caught.

The "ThreadException" is the event handler for handling UI thread exceptions and the "UnhandledException" is the event handler for handling non-UI thread exceptions. If exceptions occurred within our application we will handle them.

When either one of the following exception occurred we would like to show a friendly message to the user, log the exception, allow the user to select whether to close the application or continue if possible and notify the administrator.

My Solution

First, lets add a new Form and call it ExceptionBox

image

You will want to set the style and look of this window…I am going to leave it for you to think about it. Next we need to register to the events: ThreadException and UnhandledException. In order to do that add the following code:

public static void RegisterExceptionBoxForUnhandledExceptions()
{
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{

    MessageBox.Show(
        "An unhandled exception occurred",
        "Error",
        MessageBoxButtons.OK,
        MessageBoxIcon.Error
        );
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    MessageBox.Show(
        "An unhandled exception occurred within a thread",
        "Error",
        MessageBoxButtons.AbortRetryIgnore,
        MessageBoxIcon.Error
        );
}

Now, you will need to use the ExceptionBox. When your application starts, you need to initialize the exception box as follows:

ExceptionBox.RegisterExceptionBoxForUnhandledExceptions();

A good place will be within the Main method…

To sum things up…

We all saw applications crashes, however if we are domed to crash, we would like our application to crash gracefully.

Use this ExceptionBox and handled your unhandled exceptions…

Updates

Additional reading:

kick it on DotNetKicks.com

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

2 תגובות

  1. Shlomo8 בדצמבר 2008 ב 3:38

    נחמד מאוד
    אבל אם אנחנו רוצים לתפוס שגיאה מ
    thread
    אחר, ולעצור אותו צריך להוסיף ב
    config:
    אפשר לקרוא עוד ב:
    http://msdn.microsoft.com/en-us/library/ms228965(VS.80).aspx

    http://blogs.microsoft.co.il/blogs/yitzhak/archive/2008/01/17/unhandled-exceptions.aspx

    להגיב
  2. kolbis8 בדצמבר 2008 ב 6:44

    Shlomo, thanks for the response. I do not fully agree…Let me explain it. We have two handlers: the "ThreadException" which is the event handler for handling UI thread exceptions and the "UnhandledException" handler for handling non-UI thread exceptions. So, if exceptions occurred within our application we will handle them…However, if there will be exceptions from outside our managed code, we will not catch them. If we will set the flag legacyUnhandledExceptionPolicy we will cause the behavior we had .NET 1.1/1.0. No exceptions will be handled by our ExceptionBox.

    להגיב