views:

473

answers:

3

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.

+2  A: 

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" />
Dan Diplo
Then how would I retrieve the exception details?
+1  A: 

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.

Joseph
Yes, HandleError won't actually do anything unless you have customErrors on in the config.
swilliams
I still need to be able to retrieve and log the exception details. Preferrably, I would be able to do this in the controller action that the defaultRedirect points to.
@iguananet That is what ELMAH does. If you want to do it separately then that's a whole different matter, but it works very well. I would highly recommend giving it a try.
Joseph
@Joseph-- Thanks, but I'd like to find the simplest way to do it without any dependencies or new things to introduce into my project.
A: 

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.

swilliams