<

Centralized Exception handling in .NET Windows Forms Applications

Published on
9,827 Points
1,927 Views
4 Endorsements
Last Modified:
Approved
There is an easy way, in .NET, to centralize the treatment of all unexpected errors.

First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to that Sub in the Application tab of the project's Properties Window (last entry in the Project menu). You must make sure that Enable application framework is unchecked for this to work, because what that does is simply write a Sub Main for you, and you cannot have two of these in the same application.

Professional programmers use that approach for most applications, because it enables them to check the environment and set things up before loading the main Form. It also enables you to launch the application in different ways on in different Forms, depending on the situation, command line arguments or the user.

But over all, it enables you to trap Exception events at the application level. Here is the basic code for that module.
Module Module1

 Public Sub Main()

    AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler
    AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler

    Application.Run(New Form1)

 End Sub

 Private Sub UnhandledExceptionHandler(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
    YourReportingMethod(CType(e.ExceptionObject, Exception))
 End Sub

 Private Sub ThreadExceptionHandler(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
    YourReportingMethod(e.Exception)
 End Sub

 Private Sub YourReportingMethod(e As Exception)
    MessageBox.Show(e.Message)
    Application.Exit
 End Sub

End Module

Open in new window

The last method (you can give it any name you want) is your unexpected exception handler. Do whatever you want there. Log the exception in the event log, in a database or in a file. Report the exception in a mail message. Play some soothing music and apologize for your mistake. All of these.

You will end up in that routine anytime an Exception is triggered in code that is not inside of a Try...Catch block. Note that it receives the Exception as an argument, so you have all the necessary information needed to help you pinpoint what happened. If you install a Debug version of your application on your user's computer, the StackTrace will also pinpoint the exact line of code where the error occured. This can be useful when distribute your first few versions that always contain unexpected problems.

You can also make it a point, when you have a Try...Catch, to systematically call that routine whenever an unexpected Exception is triggered. You can do it with blocks that end like the following:
Try
   'Your code
Catch ex As SqlException
   'SQL Exception handling
Catch ex As IO.EndOfStreamException
   'Unexpected end of the file
Catch ex As IOException
   'File Exception handling
Catch
   Throw
End Try

Open in new window

The Catch...Throw at the end does the trick. It will send the Exception up the stack trace. If you terminate all your Try...Catch blocks that way, unhandled exceptions will always bubble up to your centralized error handling routine.

You will see some programmers Catch ex As Exception and Throw ex instead of a simple Catch/Throw. This works, but resets the StackTract to the line on which you call Throw ex. You won't be able to know what happened before the Throw, only the exception that was triggered. This is not very useful, so go for the Catch/Throw.

Some programmers do not like that approach, because the Exception that bubbles up could be trapped by another Try...Catch up the calls line. If this is your way of thinking, simply make your reporting method Public instead of Private as I did, Catch ex As Exception instead of simply Catch, and call your routine, passing it the ex that you catched.

This is a .NET technique, so it also works in C# and most languages supported for Windows Applications.
 
4
Comment
0 Comments

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Join & Write a Comment

The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses
Course of the Month15 days, 15 hours left to enroll

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month