Application_Error not firing when customerrors = "On"

Viewed 56411

I have code in the global.asax file's Application_Error event which executes when an error occurs and emails details of the error to myself.

void Application_Error(object sender, EventArgs e)
{
    var error = Server.GetLastError();

    if (error.Message != "Not Found")
    {
        // Send email here...
    }

}

This works fine when I'm running it in Visual Studio, however when I publish to our live server the Application_Error event does not fire.

After some testing I can get the Application_Error firing when I set customErrors="Off", however setting it back to customErrors="On" stops the event from firing again.

Can anyone suggest why Application_Error would not be firing when customErrors are enabled in the web.config?

9 Answers

I found an article which describes a much cleaner way of making custom error pages in an MVC3 web app which does not prevent the ability to log the exceptions.

The solution is to use the <httpErrors> element of the <system.webServer> section.

I configured my Web.config like so...

<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="-1" />
  <remove statusCode="500" subStatusCode="-1" />
  <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
  <error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>

I also configured customErrors to have mode="Off" (as suggested by the article).

That makes the responses overriden by an ErrorController's actions. Here is that controller:

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult NotFound()
    {
        return View();
    }
}

The views are very straightforward, I just used standard Razor syntax to create the pages.

That alone should be enough for you to use custom error pages with MVC.

I also needed logging of Exceptions so I stole the Mark's solution of using a custom ExceptionFilter...

public class ExceptionPublisherExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext exceptionContext)
    {
        var exception = exceptionContext.Exception;
        var request = exceptionContext.HttpContext.Request;
        // log stuff
    }
}

The last thing you need to so is register the Exception Filter in your Global.asax.cs file:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new ExceptionPublisherExceptionFilter());
    filters.Add(new HandleErrorAttribute());
}

This feels like a much cleaner solution than my previous answer and works just as well as far as I can tell. I like it especially because it didn't feel like I was fighting against the MVC framework; this solution actually leverages it!

Related