Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global error handling (outside of controller) in ASP.NET MVC

Let's say I put the following code somewhere in a Master page in my ASP.NET MVC site:

throw new ApplicationException("TEST");

Even with a [HandleError] attribute placed on my controller, this exception still bubbles up. How can I deal with errors like this? I would like to be able to route to an Error page and still be able to log the exception details.

What is the best way to deal with something like this?

Edit: One solution I was considering would be to add a a new controller: UnhandledErrorController. Can I put in an Application_Error method in Global.asax and then redirect to this controller (where it decides what to do with the exception)?

Note: the defaultRedirect in the customErrors web.config element does not pass along the exception info.

like image 898
user10789 Avatar asked Aug 31 '09 17:08

user10789


4 Answers

Enable customErrors:

<customErrors mode="On" defaultRedirect="~/Error">
    <error statusCode="401" redirect="~/Error/Unauthorized" />
    <error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>

and redirect to a custom error controller:

[HandleError]
public class ErrorController : BaseController
{
    public ErrorController ()
    {
    }

    public ActionResult Index ()
    {
        Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        return View ("Error");
    }

    public ActionResult Unauthorized ()
    {
        Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        return View ("Error401");
    }

    public ActionResult NotFound ()
    {
        string url = GetStaticRoute (Request.QueryString["aspxerrorpath"] ?? Request.Path);
        if (!string.IsNullOrEmpty (url))
        {
            Notify ("Due to a new web site design the page you were looking for no longer exists.", false);
            return new MovedPermanentlyResult (url);
        }

        Response.StatusCode = (int)HttpStatusCode.NotFound;
        return View ("Error404");
    }
}
like image 86
Todd Smith Avatar answered Oct 28 '22 09:10

Todd Smith


As MVC is built on top of asp.net you should be able to define a global error page in web.config, just like you could in web forms eg.

   <customErrors mode="On" defaultRedirect="~/ErrorHandler" />
like image 28
Dan Diplo Avatar answered Oct 28 '22 11:10

Dan Diplo


You can create a Filter that looks for an Exception in the OnActionExecuted method:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class WatchExceptionAttribute : ActionFilterAttribute {
  public override void OnActionExecuted(ActionExecutedContext filterContext) {
    if (filterContext.Exception != null) {
      // do your thing here.
    }
  }
}

Then you can put [WatchException] on a Controller or Action Method, and it will let log exceptions. If you have a lot of Controllers, that might be tedious, so if you have a common Base Controller you can override OnActionExecuted there and do the same thing. I prefer the filter method.

like image 32
swilliams Avatar answered Oct 28 '22 09:10

swilliams


As far as what page to display, you'll need to create a customErrors section in your web.config and set it up for whatever status codes you want to handle.

Example:

<customErrors defaultRedirect="GenericError.htm" mode="RemoteOnly">
  <error statusCode="500" redirect="InternalError.htm"/>
</customErrors>

As far as logging exceptions, I would recommend using ELMAH. It integrates nicely with ASP.NET MVC sites.

like image 30
Joseph Avatar answered Oct 28 '22 09:10

Joseph