Exception Handling in ASP.NET MVC

Here you will learn how to handle exceptions in ASP.NET MVC application.

You may handle all possible exceptions in the action methods using try-catch blocks. However, there can be some unhandled exceptions that you want to log and display custom error messages or custom error pages to users.

When you create an MVC application in Visual Studio, it does not implement any exception handling technique out of the box. It will display an error page when an exception occurred.

For example, consider the following action method that throws an exception.

Example: Action Method
namespace ExceptionHandlingDemo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Contact()
        {
            string msg = null;
            ViewBag.Message = msg.Length; // this will throw an exception

            return View();
        }
}

Navigating to /home/contact in the browser, and you will see the following yellow page (also known as the Yellow Screen of Death) that shows exception details such as exception type, line number and file name where the exception occurred, and stack trace.

Default error page in MVC
Default Error Page in MVC

ASP.NET provides the following ways to handle exceptions:

  1. Using <customErrors> element in web.config
  2. Using HandleErrorAttribute
  3. Overriding Controller.OnException method
  4. Using Application_Error event of HttpApplication

<customErrors> Element in web.config

The <customErrors> element under system.web in web.config is used to configure error code to a custom page. It can be used to configure custom pages for any error code 4xx or 5xx. However, it cannot be used to log exception or perform any other action on exception.

Enable the <customErrors> in web.config, as shown below.

Example: Enable customErrors
<system.web> 
    <customErrors mode="On"></customErrors>
</system.web> 

You also need to add HandleErrorAttribute filter in the FilterConfig.cs file.

Example: Add HandleErrorAttribute Filter
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

After enabling the customErrors mode to On, an ASP.NET MVC application will show the default custom error page, as shown below.

Custom Error Page

The above view is Error.cshtml in the Shared folder. It will be displayed on the 500 error code.

The HandleErrorAttribute filter set the Error.cshtml as the default view to display on an error occurred.

Learn more about handling exceptions using web.config customErrors in ASP.NET MVC.

HandleErrorAttribute

The HandleErrorAttribute is an attribute that can be used to handle exceptions thrown by an action method or a controller. You can use it to display a custom view on a specific exception occurred in an action method or in an entire controller.

Note:
The HandleErrorAttribute attribute can only be used to handle the exception with status code 500. Also, it does not provide a way to log exceptions.

In order to use this attribute, you must add HandleErrorAttribute filter in the FilterConfig.RegisterGlobalFilters() method and also, set the mode attribute to On <customErrors mode="On"> in web.config, as we did for the customErrors section above.

Now, let's apply [HandleError] attribute to the action method, as shown below.

Example: HandleErrorAttribute
public class HomeController : Controller
{
    [HandleError]
    public ActionResult Contact()
    {
        string msg = null;
        ViewBag.Message = msg.Length;
            
        return View();
    }
}

Above, we configured [HandleError] attribute on the Contact() action method. It will display Error.cshtml view from the Shared folder when an exception occurs. The [HandleError] set the Error.cshtml view as default view for any exceptions.

the [HandleError] can also be used to configure different pages for different types of exceptions, as shown below.

Example: Configure Views for Exceptions
public class HomeController : Controller
{
    [HandleError]
    [HandleError(ExceptionType =typeof(NullReferenceException), View ="~/Views/Error/NullReference.cshtml")]
    public ActionResult Contact()
    {
        string msg = null;
        ViewBag.Message = msg.Length;
            
        return View();
    }
}

Now, the above example will show NullReference.cshtml because it throws NullReferenceException.

The [HandleError] attribute has a limited scope and not recommended to use in most cases.

Overriding Controller.OnException Method

Another way to handle controller level exceptions is by overriding the OnException() method in the controller class. This method handles all your unhandled errors with error code 500.

It allows you to log an exception and redirect to the specific view. It does not require to enable the <customErrors> config in web.config.

Example: Handle Exceptions in the Controller
public class HomeController : Controller
{
    public ActionResult Contact()
    {
        string msg = null;
        ViewBag.Message = msg.Length;
            
        return View();
    }
    
    protected override void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;

        //Log the error!!
     
        //Redirect to action
        filterContext.Result = RedirectToAction("Error", "InternalError");

        // OR return specific view
        filterContext.Result = new ViewResult
        {
            ViewName = "~/Views/Error/InternalError.cshtml"
        };
   }
} 

Using Application_Error event of HttpApplication

The ideal way to log exception occurred in any part of your MVC application is to handle it in the Application_Error event in the global.asax file.

Example:
public class MvcApplication : System.Web.HttpApplication
{
    //other code removed for clarity

    protected void Application_Error()
    {
        var ex = Server.GetLastError();
        //log an exception
    }
}

The Application_Error event is fired on any type of exception and error codes. So, handle it carefully.

Recommendation

In most web applications, you should ideally log the exceptions and also show appropriate error messages or pages to the users. So, it is recommended to use the global Application_Error event to log all the exceptions along with <customErrors> element in web.config to redirect it to appropriate pages.

The above exception handling techniques will return the response with 200 status code. If you are concern to return specific error code in response then you have to use <httpErrors> element in web.config. Learn how to display a custom error page with the appropriate error code in ASP.NET.