This blog is moved to
http://amalhashim.wordpress.com

Friday, March 13, 2009

Catch All Exceptions

As you may know, an exception is always thrown in the context of a running thread; what happens if there is no try...catch block protecting that thread? The exception is propagated to the application domain level, where, eventually, it will cause your application to crash.

Since you cannot be sure that all threads are running (and you may not want to do so, anyway) inside a try...catch block, there are two things you can do to, 1) at least, be notified when an exception occurs and 2) decide what to do when that happens. In a Windows Forms application, the System.Windows.Forms.Application class is where this is done.

The argument to Application.SetUnhandledExceptionMode can be one of:

* UnhandledExceptionMode.Automatic: exception is caught in the Application.ThreadException handler, if there is no entry in the App.config or Web.config that disables it
UnhandledExceptionMode.CatchException: exception is caught in the ThreadException handler
UnhandledExceptionMode.ThrowException: exception is thrown, the ThreadException handler is ignored

See this example:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);

Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

void Application_ThreadException(Object sender, ThreadExceptionEventArgs e)

{

//do something with e.Exception

}

If you don't have a Windows Forms application, but instead a console application or a Windows Service, you can still catch all exceptions at the application domain level:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

void CurrentDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e)
{

//Object exception = e.ExceptionObject;
//Boolean terminating = e.IsTerminating;
}

Finally, if you have an ASP.NET application, you add an event handler to the HttpApplication.Error event. This can be done in several ways:

1) Add an event handler to the Error event from anywhere (a page, a control, a module, etc):

HttpContext.Current.ApplicationInstance.Error += new EventHandler(ApplicationInstance_Error);

void ApplicationInstance_Error(object sender, EventArgs e)
{

//Exception ex = HttpContext.Current.Server.GetLastError();
//HttpContext.Current.Server.ClearError();

}
2) Implement the Application_Error method on Global.asax.cs:

protected void Application_Error(Object sender, EventArgs args)

{

//Exception ex = HttpContext.Current.Server.GetLastError();
//HttpContext.Current.Server.ClearError();

}

3) Implement a custom IHttpModule and hook to the Error event (my favorite):

public class ErrorModule: IHttpModule

{

public void Init(HttpApplication app)

{

app.Error += Application_Error;

}

void app_Error(object sender, EventArgs e)
{
//Exception ex = HttpContext.Current.Server.GetLastError();
//HttpContext.Current.Server.ClearError();

}

}

No comments: