Global Exception Handler (WinForms)
Posted
Wed, Sep 2 2009 12:52
by
Deborah Kurata
Application failures will occur. The user could perform a sequence of
operations or enter a value that you don’t expect, the connectivity to your
database could be interrupted, the code could have a logic error, or many
other possibilities. The .NET Framework provides structure exception
handling (SEH) to help you manage application failures.
An exception is a failure that occurs in your application. Exceptions
fall into two broad categories: expected and unexpected.
Expected exceptions are those that your application plans for and
responds to. For example, you expect that a user-requested customer may
not be found in the database. So you add code to check for this condition
and respond with an appropriate message to the user.
Unexpected exceptions are those that you know may happen, but
don’t necessarily know when or where. These are more difficult to plan for.
Logic errors are a good example of this type of exception. This is especially
true in cases where the logic error corrupts some underlying data and the
exception occurs later when that data is processed, possibly far from the
actual logic error.
Structured exception handling allows you to define a code structure
to handle both expected and unexpected exceptions generated in your application. This is the purpose of the Try/Catch blocks provided in the .NET
Framework.
The goal of exception handling is to never allow the application to abort
with a system error. Your application should handle all expected and unexpected exceptions.
In the case of unexpected exceptions, handle the exception by logging exception details to a file or some other source so that you can more quickly determine the cause of the exception. Then you can display a user-friendly message to the user and terminate the application gracefully.
To catch every possible exception in a Windows Forms application, you need to do one of the following:
- Ensure that every application entry point has a Try/Catch block to
catch every possible exception.
This is actually much harder than it sounds. Since your application
is event-driven, every event is a possible entry point into your application code. So you would have to add a Try/Catch block to every
event handler in your application. - Write code in the appropriate unhandled exception event.
This post focuses on the second option: writing code in an appropriate unhandled exception event. Implement a global exception handler in a Windows Forms application as follows.
In C#:
In C#, you can trap the ThreadException event.
- Select a Windows Application project in Solution Explorer.
- Open the generated Program.cs file by double-clicking on it.
- Add the following line of code to the top of the code file:
using System.Threading;
- In the Main() method, add the following as the first line of the method:
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
- Add the following below the Main() method:
static void Application_ThreadException(
object sender, ThreadExceptionEventArgs e)
{
// Do logging or whatever here Application.Exit();
}
- Add code to handle the unhandled exception within the event
handler.
Any exception that is not handled anywhere else in the application is
handled by the above code. Most commonly, this code should log the error and display a message to the user.
NOTE: This code does not really "handle" the error. It just provides a place to log the error, perform any clean up operations, and display a message to the user. Unless you exit the application as shown in the sample code above, the code will attempt to continue, but will most likely be in an invalid state.
NOTE: This code only handles unhandled exceptions from the main UI thread. If you create other threads, they will need their own exception handling.
In VB:
With VB, Windows applications provide application events. One of these application events is the UnhandledException event, which the application generates whenever an unhandled exception occurs. You can write code for this event to catch any exception not specifically handled by your application.
- Select a Windows Application project in Solution Explorer.
- Open the Project Designer for the project by right-clicking the
project and selecting Properties from the context menu, OR select
Project | Properties from the main menu bar, OR double-click on
the My Project folder under the project.
- Select the Application tab of the Project Designer if it is not
already selected.
- Ensure that the Enable application framework checkbox is
checked.
- Click the View Application Events button.
An ApplicationEvents.vb code file is added to your project, if it does
not already exist, and is opened. The generated code is as follows: Namespace My
' The following events are available for MyApplication:
'
' Startup: Raised when the application starts, before the startup form is created.
' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally.
' UnhandledException: Raised if the application encounters an unhandled exception.
' StartupNextInstance: Raised when launching a single-instance application and the application is already active.
' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
Partial Friend Class MyApplication
End Class
End Namespace
- Select (My Application Events) from the Class Name dropdown
at the top left of the Code Editor.
- Select UnhandledException from the Event drop-down at the
top right of the Code Editor. The following event handler code lines are generated:
Private Sub MyApplication_UnhandledException( _
ByVal sender As Object, ByVal e As _
Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) _
Handles Me.UnhandledException End Sub
- Add code to handle the unhandled exception within the event
handler.
Any exception that is not handled anywhere else in the application is
handled by this code. Most commonly, this code should log the error and
display a message to the user.
NOTE: The VB UnhandledException event never occurs when you are running
with the debugger. When you are running with the debugger, Visual Studio catches the error and assists you with debugging it. To test the code in this event, use the option to "Start Without Debugging".
By setting up a global exception handler, you can ensure that your application catches any unexpected exception and never displays an unfriendly message to your users.
(Based on an except from "Doing Objects in Visual Basic 2005".)
Enjoy!