Search
| Login
corner corner
Relevant Links
corner corner
corner corner
Subscribe To Feed
corner corner
corner corner
Search Articles
corner corner
corner corner
Topics
corner corner
corner corner
Article List
corner corner
corner corner
Article Archive
corner corner
corner corner
Survey
Which platform does your company use?



Submit Survey  View Results
corner corner
corner corner
Relevant Links
corner corner
corner corner
Global Catch All Exception in .NET Winform and Console Application
Location: BlogsCubicZone.NET    
Posted by: cubiczone 8/6/2007 2:49 PM

As a good programmer, you normally want to catch all exceptions at the highest tier in code so that your program has the chance to display the error message to the user or log it to the appropriate location. Under ASP.NET, you can do so easily by overriding the Application_Error event in Global.asax file.

protected void Application_Error(Object sender, EventArgs e)
{
 Exception ex = Server.GetLastError();
 
 // Perform error logging here...

 // Clear the error and maybe redirect to some other page...
 Server.ClearError();
}

Unfortunately, there is no concept of Global.asax in a winform or console application in .NET. In a windows form application, the equivalent global catch all is available by listening to the ThreadException and AppDomain UnhandledException events.

[STAThread]
static void Main()
{
 // Catch all unhandled exceptions
 Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);

 // Catch all unhandled exceptions in all threads.
 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);

 Application.Run(new MainForm());
}

private static void ThreadExceptionHandler(object sender, ThreadExceptionEventArgs args)
{
 try
 {
  // Log error here or prompt user...
 }
 catch { }
}

private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
 try
 {
  // Log error here or prompt user...
 }
 catch { }
}

The event model is slightly more complicated in a winform application because you typically have more than one thread that you hand manage unlike in ASP.NET where threads are shielded from you in the form of page requests. Other than that, just implementing these two events will get you out of a lot of trouble and helps find those nasty runtime bugs. Have fun!

Permalink |  Trackback

Comments (4)   Add Comment
Re: Global Catch All Exception in .NET Winform and Console Application    By Matt on 8/14/2007 7:39 PM
@Slim -

Good post. I'd say this a bit differently though:

<< ...you normally want to catch all exceptions at the highest tier in code so that your program has the chance to display the error message to the user or log it to the appropriate location. >>

I'd say that in general, you want to catch exceptions at the *lowest* possible level in code, closest to where the exception occurs, and then make the decision about what to pass to the layer above. However, if the exception is such that either program execution cannot reasonable continue or if the user must be notified of the exception (as in some operation that is unrecoverable and requires user interaction) then you want to do what you are recommending in the blog post.

Matt

Re: Global Catch All Exception in .NET Winform and Console Application    By Stephen on 8/15/2007 6:45 AM
Yes, you do want to be aware of any exception that will be thrown at the lowest level in code and handle it there (such as dispose objects, clean up connections, etc). Eventually, you likely want to surface these exceptions to the interface (prompt user, log to file, etc) or at least have a general catch-all at the highest tier for any other exceptions that you may have missed. In this case, I was uniquely referring to a "catch-all" exception at the highest tier. :)

Re: Global Catch All Exception in .NET Winform and Console Application    By Ilia Broudno on 8/18/2008 2:12 PM
I tried your code and while it does catch exceptions if they happen on the main (UI) thread, it fails to catch Exceptions thrown by backgroundWorker threads.

Re: Global Catch All Exception in .NET Winform and Console Application    By Ilia Broudno on 8/18/2008 3:10 PM
To answer my own question:

BackgroundWorker catches exceptions and passes them into the RunWorkerCompleted event handler, where it is exposed as the Error property of System.ComponentModel.RunWorkerCompletedEventArgs.

see more at http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx

I don't know if your example works for threads that are managed at lower level, but if you are using BackgroundWorker to manage your threads like I do, you need to implement your error handling in your RunWorkerCompleted event handler.

One more criticism of the above example:
If your error handler throws an excpetion and you have used the above example to catch them, your app will be thrown into an infinite loop of throwing and catching exceptions.

So for catching exceptions that happen on the UI thread you are better off using a try catch around your
Application.Run(new MainForm());

My objective was to capture all exceptions and handle them by sending an email to tehnical group, making an event log entry or whatever else you might need and then to re-throw the exception so that it pops up as unhandled.
I Achived that by first Creating a static class ErrorHandler with a static method Report that handles the excpetion and then re-throws it.
Then I added the following in backgroundWorker_RunWorkerCompleted

private void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
........................
if (e.Error != null)
ErrorHandler.Report(sender, e.Error);
..........................



and then in Program.Main I added:

MainForm mf = new MainForm();
try
{
Application.Run(mf);
}
catch (Exception ex)
{
ErrorHandler.Report(mf, ex);
}

This makes sure that UI thread excpetions are also handled.


Your name:
Title:
Comment:
Add Comment   Cancel 
corner corner