Capturing application-wide unhandled exceptions

I’m now two months into my new job and am neck-deep in development on the two web applications that my team maintains. One thing I’ve noticed so far in the code base is that there are many areas throughout the application where try/catch blocks should have been used, but were not. This often leads to users seeing ASP.NET exception error pages when unexpected errors occur.

To quickly address this issue, I’m implementing application-wide exception handling, so that at least users see a nice error page and can continue on with their work. With ASP.NET web applications, there is a super-easy way to get this going: Use the Application_Error() method in the Global.asax file.

Global.asax.cs:

protected void Application_Error(Object sender, EventArgs e)
{
   if (Server.MachineName.ToUpper() == PRODUCTION_MACHINE)
   {
      Exception ex = Server.GetLastError().GetBaseException();

      // When an exception occurs, session is no longer available
      // in this method. Store exception at Application-level instead.
       string guid = Guid.NewGuid().ToString;
      Application.Add(guid, ex);

      Server.Transfer("./error.aspx?e=" + guid);
   }
}

So, what this code does is this:

  1. Check to see if we’re on the Production machine. (Of course, initialize the PRODUCTION_MACHINE to be the machine name of your Production web server.)
  2. If so, then get the last error and save that at the Application-level, so that we can access it on another page. Use a GUID as the key, so that we can retrieve it later.
  3. Then, transfer the user to the generic error page.

Note: You’ll notice that I did not use Session anywhere in this method. Our web applications are using the ASP.NET State Server to store our sessions and this causes the Session to temporarily become null when an unhandled exception occurs and this method executes. Once this method finishes executing and the code-behind in the error.aspx page begins to execute, we can again access Session.

If you are using the InProc session state, you may be able to store the exception in the Session instead.

Anyway, once we transfer the user to the generic error page, we can do any sort of error processing we want. My current implementation displays a friendly error message to the user, then emails our team the details of the exception, including relevant information from the user’s Session.

error.aspx.cs:

private void Page_Load(object sender, System.EventArgs e)
{
   // Get the exception
   string guid = Request.QueryString["e"];
   Exception ex = (Exception) Application[guid];
   Application.Remove(guid); // Little bit of cleanup

   // Insert any code here to display error message to user

   // Insert code to email exception to yourself
}


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *