6

I am using ELMAH to log unhandled exceptions in an ASP.NET Webforms application. Logging is working fine.

I want to pass the ELMAH error log id to a custom error page that will give the user the ability to email an administrator about the error. I have followed the advice from this answer. Here is my global.asax code:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{        
    Session[StateKeys.ElmahLogId] = args.Entry.Id;

    // this doesn't work either:
    // HttpContext.Current.Items[StateKeys.ElmahLogId] = args.Entry.Id;
}

But, on the Custom error page, the session variable reference and HttpContext.Current.Items are giving me a NullReference exception. How can I pass the ID to my custom error page?

Community
  • 1
  • 1
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346

2 Answers2

7

This works for me:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
    if (args.Entry.Error.Exception is HandledElmahException)
        return;

    var config = WebConfigurationManager.OpenWebConfiguration("~");
    var customErrorsSection = (CustomErrorsSection)config.GetSection("system.web/customErrors");        

    if (customErrorsSection != null)
    {
        switch (customErrorsSection.Mode)
        {
            case CustomErrorsMode.Off:
                break;
            case CustomErrorsMode.On:
                FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect);
                break;
            case CustomErrorsMode.RemoteOnly:
                if (!HttpContext.Current.Request.IsLocal)
                    FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect);
                break;
            default:
                break;
        }
    }        
}

void FriendlyErrorTransfer(string emlahId, string url)
{
    Server.Transfer(String.Format("{0}?id={1}", url, Server.UrlEncode(emlahId)));
}
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • 2
    Where `HandledElmahException` is a custom class as described in your answer [here](http://stackoverflow.com/a/2906221/39396) – Carl G Apr 18 '13 at 05:38
  • 4
    Did you ever get a "Error executing child request..." with `Server.Transfer`? – Carl G Apr 18 '13 at 06:30
2

Unable to comment on Ronnie's solution. I had that in place for a while but it breaks the standard error flow process and causes ErrorLog_Logged to always transfer, even when calling

Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

This is a problem if you still want to log an error from within a catch statement, for instance you have a workaround for an error but want to log the error to perform a proper fix, which can be pretty helpful on difficult to replicate issues.

I was able to correct this by using the following change:

//if (customErrorsSection != null)    
if (customErrorsSection != null && this.Context.Error != null)

This respects the typical error handling properly, as the context.Error will be null in cases where you explicitely raise the exception in Elmah, but is not null when falling through default error handling (not via a catch or if caught and re-thrown). This causes Ronnie's solution to respond similar to the .Net error handling logic.

  • I stopped using Elmah quite a while ago. It's easier to log your errors yourself. – Ronnie Overby Jun 20 '14 at 13:07
  • Yeah, I don't know if I would go down the Elmah road again either. It's handy because it does nice presentation or the stack trace without a lot of work, but it usually leaves me wanting to extend it, change the data structure and other things that usually just aren't worth the effort involved with it. – user2701750 Jul 08 '14 at 17:44
  • Getting a stack trace doesn't really get much easier than calling exception.ToString()... Includes exception type, message, and call stack and recurses through the inners. – Ronnie Overby Jul 08 '14 at 22:15
  • Tested this by throwing a new Exception("blah") in MVC5 and this.Context.Error was null. Unfortunate as it would be nice to be able to raise errors without having to wrap them in a different exception as in the accepted answer. – phloopy Jul 22 '14 at 23:25