Many ASP.NET developers think that having code in the Application_Error method in Global.asax.cs is adequate for dealing with any unhandled exceptions within their web application. While it usually is adequate--for most basic web applications, there are particular cases where this simply won't catch all errors.
Specifically, if you have code running on the server that is in a thread pool, or you've spawned a separate thread, or you have callback code for a timer, if an unhandled exception occurs, you just might be out of luck.
You can easily test this for yourself by creating a web page with two buttons, one that throws an exception when you click it, and the other that uses a thread from the thread pool and throws an exception within it. Something like this:
public partial class _Default : System.Web.UI.Page { private void ThrowException() { throw new ApplicationException("Ouch!"); } protected void Button1_Click(object sender, EventArgs e) { ThrowException(); } protected void Button2_Click(object sender, EventArgs e) { System.Threading.ThreadPool.QueueUserWorkItem( new System.Threading.WaitCallback(DoWork)); } private void DoWork(object dummy) { ThrowException(); } }
In addition to the HttpUnhandledException that gets sent to the Application_Error method, you need to handle the UnhandledException event on the AppDomain.
You can set up a handler in the Application_Start method in Global.asax.cs. But if you go a step further, you can create something a little more reusable. Here's an HttpModule that will demonstrate handling both kinds of web exeptions--those occurring during a normal web request, and those occurring on separate threads. Perhaps it should be part of the Logging Framework.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using BitFactory.Logging; namespace WebAppA { public class MyExceptionModule : IHttpModule { private HttpServerUtility Server { get; set; } #region IHttpModule Members public void Dispose() { } public void Init(HttpApplication context) { // deal with any non-main thread exceptions AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); // deal with any HttpUnhandledExceptions context.Error += new EventHandler(context_Error); Server = context.Server; } void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { // If we are here, the process is about to die ConfigLogger.Instance.LogFatal(((Exception)e.ExceptionObject).Message); } void context_Error(object sender, EventArgs e) { // The outer exception is usually an HttpUnhandledException, so use the InnerException if it exists. // Even more detail can be retrieved by iterateing over each InnerException, if desired. Exception ex = Server.GetLastError(); ex = ex.InnerException ?? ex; ConfigLogger.Instance.LogError(ex.Message); } #endregion } }
Modify the above to suit your needs. In addition, the following would go into your web.config file.
<httpModules> <add name="MyExceptionModule" type="WebAppA.MyExceptionModule, WebAppA" /> </httpModules>
You might consider putting something like this into a separate utility assembly that you can reuse in all your web projects.
Copied from Elmah?
ReplyDeleteElmah logs unhandled exceptions in ASP.NET apps, and provides some nice ways to views those exceptions. I have a complete logging framework that allows you to log exceptions or any other events from ASP.NET, WinForms, Services, console apps, or anything .NET. The module I provided in this post is a very simple--and very handy--addition to an ASP.NET web application. It's short and sweet, and does just about everything you need (when accompanied by the logging framework) without adding yet another 150K+ DLL to your project.
ReplyDeletePut your code in my WebForms WebSite project and Init() getting called but CurrentDomain_UnhandledException() and context_Error() are not getting called. This article is pretty old. Could something have changed that makes this code not work anymore.
ReplyDeleteHarrah's Las Vegas Casino and Hotel - Mapyro
ReplyDeleteThe 이천 출장마사지 hotel's curved glass façade and floor-to-ceiling windows feature large, custom-built windows with separate, 안양 출장샵 separate, 남원 출장마사지 and separate windows. 인천광역 출장샵 Rooms 춘천 출장마사지 and