London Calling

Ramblings of a software architect in London.

Error Handling and Exception Logging

I’ve been struggling with Anthem.NET for some time to work exactly how I would like (and expect) as regards to the event flow for an unhandled page exception.

In the original 1.5.1 release of Anthem, the Application_Error event was bypassed by a hook added in Manager.OnError as follows:

   1: private void OnError(object source, EventArgs e)
   2: {
   3:     if (IsCallBack)
   4:     {
   5:         _error = HttpContext.Current.Error.ToString();
   6:         HttpContext.Current.ClearError();
   7:         WriteResult(HttpContext.Current.Response, null, _error);
   8:     }
   9: }

Which meant that any global logging (we use log4net) of an error that you do in Application_Error does not fire and so you end up with the unsatisfactory situation where errors in callbacks occur silently to your operations team whilst returning correct information back to the JS client portion of Anthem.

This can be worked around by writing a JS Anthem error handler that then calls an AJAX method which triggers a log of a message, but that is convoluted, inefficient and unrelhable and not an acceptable solution for me.

In the latest source of AnthemNxt I’ve removed the above OnError handler and let the exception proceed as a normal postback would (so my Application_Error handler DOES get hit now and I get exceptions fully logged).

However now there is a HTML error page returned to the JS client and not a valid JSON response because the OnUnload Anthem handler is never called (since the page rendering is hijacked due to the exception). Until I can write a HttpModule to overcome this and make AnthemNxt a true drop-in library, I’ve broken out the OnUnload AnthemNxt functionality so that it can be called from Application_Error:

   1: private void OnUnload(object sender, EventArgs e)
   2: {
   3:     CompleteRequest();
   4: }
   5:
   6: public void CompleteRequest()
   7: {
   8:     var res = HttpContext.Current.Response;
   9:
  10:     // Handles inserting JS to do a redirect 
  11:     if(Manager.IsCallBack && res.StatusCode == 302)
  12:     {
  13:         string href = res.RedirectLocation.Replace("", "\").Replace("'", "'"); 
  14:         res.RedirectLocation = string.Empty;
  15:         res.Clear();
  16:         res.StatusCode = 200;
  17:
  18:         var sb = new StringBuilder();
  19:         Manager.AddScriptForClientSideEval("window.location='" + href + "';");
  20:         JsonWriter.WriteValueAndError(sb, null, null, null, null, null, null, null, clientSideEvalScripts);
  21:         res.Write(sb.ToString());
  22:         res.End();
  23:     }
  24: }

as so:

   1: protected void Application_Error(object sender, EventArgs e)
   2: {
   3:     log.Error(ex.Message, ex);
   4:
   5:     // If we are in debug mode get the usual "yellow screen of death" up, makes debugging easier during development 
   6:     if(!Manager.IsCallBack && HttpContext.Current.IsDebuggingEnabled) return;
   7:
   8:     // Redirects to an error page - need to not end the request if this is a callback
   9:     // so that AnthemNxt can write a JS redirect into the JSON response
  10:     Response.Redirect(“~/error.aspx”, !Manager.IsCallBack);
  11:     if(Manager.IsCallBack) Manager.Current.CompleteRequest();
  12: }

Hopefully with a HttpModule I can make this fully automatic, but for our purposes this is better than the existing behaviour for now :)

Anyone interested in contributing, whether it be patches, comments or just bugs please get in touch or use the Codeplex project.

1 comment for “Error Handling and Exception Logging

  1. Ali
    April 28, 2009 at 6:36 pm

    It was very useful for me
    Thanks a lot

Leave a Reply

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