APM for All! NEW Retrace consumption pricing starts at $9.99 per month! Learn more

Best Practices for Error Handling in ASP.NET MVC

By: mwatson
 |  April 25, 2017

Error handling is an important part of any application. ASP.NET provides several different ways to handle errors. In this article, we will review MVC error handling best practices.

5 Ways to do MVC Error Handling

Between .NET, ASP.NET, and MVC there are several potential ways to handle application errors.

  • Web.Config customErrors
  • MVC HandleErrorAttribute
  • Controller.OnException method
  • HttpApplication Application_Error event
  • Collect exceptions via .NET profiling with Retrace

There are some pros and cons to all of these ways handle errors. You probably need to use a combination of them to handle properly and log errors.

There are two critical things that you need accomplish with error handling:

  1. Gracefully handling errors and show your users a friendly error page
  2. Logging errors so that you are aware of them and can monitor them

Must Have: Global Error Page With Web.Config <customErrors>

The last thing you ever want your users to see is a “yellow screen of death” type error. If you don’t know what that is, I’m referring the standard yellow ASP.NET error screen.

For any application, I would always recommend specifying a custom error page in your Web.Config. Worst case scenario, your users will see this page if an unhandled exception occurs.

<system.web>
    <customErrors mode="On" defaultRedirect="~/ErrorHandler/Index">
        <error statusCode="404" redirect="~/ErrorHandler/NotFound"/>
    </customErrors>
<system.web/>

MORE: How to Use Web.Config customErrors for ASP.NET

Use MVC HandlerErrorAttribute to Customize Responses

The HandleErrorAttribute inherits from FilterAttribute and can be applied to an entire controller or individual controller action methods.

It can only handle 500 level errors that happen within an MVC action method. It does not track exceptions that help outside of the MVC pipeline. Exceptions may occur in other HTTP modules, MVC routing, etc.

When to Use HandleErrorAttribute

Since it does not provide a way to collect all exceptions that could ever happen, it is a bad solution for a global unhandled error handler.

It works perfectly for tailoring specific error pages for a specific MVC controller or action method. Specifying an error page in your Web.Config <customErrors> works ideal for a universal error page. The HandleErrorAttribute gives you fine-grained control if you need it.

Note: HandleErrorAttribute requires customErrors to be enabled in your Web.Config.

For example, if you wanted to show a particular MVC view when a SqlException happens, you can do it with the code below:

[HandleError(ExceptionType = typeof(SqlException), View = "SqlExceptionView")]
public string GetClientInfo(string username)
{
	return "true";
}

The problem with HandleErrorAttribute is it doesn’t provide a way to log the exception!

Use MVC Controller OnException to Customize Responses

OnException is similar to HandleErrorAttribute but provides more flexibility. It works with all HTTP status codes, and not just 500 level responses. It also gives you the ability to log the errors!

public class UserMvcController : Controller
{
   protected override void OnException(ExceptionContext filterContext)
   {
      filterContext.ExceptionHandled = true;

	  //Log the error!!
      _Logger.Error(filterContext.Exception);

      //Redirect or return a view, but not both.
      filterContext.Result = RedirectToAction("Index", "ErrorHandler");
      // OR 
      filterContext.Result = new ViewResult
      {
         ViewName = "~/Views/ErrorHandler/Index.cshtml"
      };
   }
}

When to Use OnException for MVC Error Handling

If you want a way to present your users custom MVC views or custom log exceptions, OnException is a good solution for you. It provides more flexibility than HandleErrorAttribute and does not require customErrors to be enabled in your Web.Config file.

Note: OnException gets called for all HTTP status codes. So be careful how you handle simple issues like a 404 caused by a bad URL.

Use HttpApplication Application_Error as Global Exception Handler

So far we have covered three different ways to customize the response that your users see if an exception occurs. Only within OnException can you potentially log exceptions.

To log all unhandled exceptions that may occur within your application, you should implement basic error logging code as shown below.

public class MvcApplication : System.Web.HttpApplication
{
   protected void Application_Start()
   {
      AreaRegistration.RegisterAllAreas();
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);
   }

   protected void Application_Error()
   {
      var ex = Server.GetLastError();
      //log the error!
      _Logger.Error(ex);
   }
}

When to Use Application_Error

Always! HttpApplication’s Error even provides the best mechanism to collect and log all unhandled application errors.

Collect All .NET Exceptions with Stackify Retrace

Stackify’s APM solution, Retrace, taps into the .NET profiling APIs to track the performance of your app down to the code level. As part of that, it can automatically collect all unhandled exceptions or be configured to receive all exceptions ever thrown, even if they are handled and discarded. Retrace doesn’t require any code changes either!

Retrace allows you to view and monitor all of your application errors. Check out our error monitoring features to learn more.

MVC Error Handling
Screenshot from Retrace

Summary on MVC Error Handling

There are several ways to do MVC error handling. You should always specify a default error page via your web.config <customErrors> and log unhandled exceptions that get called back to your HttpApplication Error method.

You can use HandleErrorAttribute or OnException to provide fine-grained control of how you display error type messages to your users.

If you want to track all of your application exceptions, be sure to check our Retrace and our error monitoring features. You can also view all application exceptions on your workstation for free with our free profiler, Prefix.

More Resources:

 

Improve Your Code with Retrace APM

Stackify's APM tools are used by thousands of .NET, Java, PHP, Node.js, Python, & Ruby developers all over the world.
Explore Retrace's product features to learn more.

Learn More

Want to contribute to the Stackify blog?

If you would like to be a guest contributor to the Stackify blog please reach out to [email protected]