.NET

Easier error handling in ASP.NET MVC5

I’ve written a few posts about error handling in ASP.NET MVC. It’s not easy to get it right since the MVC pipeline uses a different error handling method than ASP.NET itself. With our client library you can get a fully working implementation for free, without having to using the rest of our service.

OneTrueError injects itself both in the ASP.NET pipeline and by using an integration point in MVC5. To activate OneTrueError you have to download our “onetrueerror.mvc5″ package. You can activate it by using OneTrue.Configuration.CatchMvcExceptions(). That means that all exceptions will be handled by our library without reporting them to our service. To catch and log all exceptions you can use OneTrue.Configuration.AddSubmitter(new YourLogAdapter()).

Reporting error to our service

To get all of our features you have to create an account at OneTrueError and invoke OneTrue.Configuration.Credentials(appKey, sharedSecret);

tags

When you visit our dashboard you’ll see that we are identifying tags for ASP.NET and MVC. Click on any of the tags to search StackOverflow for the error message (filtering on the tag that you clicked on).

MVC specific information

We capture MVC specific information each time we process a new exception. You get for instance information about the controller that is executing, the route that was chosen, the result that have been specified (if any).

RouteData

Do you wonder which route was used when the user got the error?

routedata

ViewBag

Are you using the ViewBag instead of a view model?

ViewBag.User = new
{
    FirstName = "Arne",
    LastName = "Colt",
    Age = 37,
    Address = new {ZipCode = 12345}
};

No worries (it’s MVC that stores it in the ViewData).

viewbag

As you can see, OneTrueError also supports nested view models (and anonymous objects).

TempData

TempData is captured too.

TempData["Transaction"] = new
{
    Amount = 20000,
    Expires = DateTime.UtcNow.AddMinutes(5)
};

tempdata

.. and more

We also collect the following HTTP/MVC specific information (if available):

  • Controller class name
  • ActionResult information
  • Child Action Context
  • HTTP Request/Form/Files/Session/QueryString
  • Information stored in HttpApplication

Error pages

When it comes to error pages we support several options.

The first option is to simply create an Error.cshtml in your Views\Shared folder.

Here is a sample file:

@model OneTrueError.AspNet.Mvc5.OneTrueViewModel
<div>
    <h1>@Model.HttpStatusCodeName</h1>
    <p>Failed to execute!</p>
</div>
<div>
    <p>@Model.Exception</p>
</div>

The ViewModel that is passed have the following information:

/// <summary>
    /// View model for all error pages used by this plugin.
    /// </summary>
    public class OneTrueViewModel
    {
        /// <summary>
        ///     Caught exception
        /// </summary>
        public Exception Exception { get; set; }
        /// <summary>
        ///     Http status code. Typically 404 or 500
        /// </summary>
        public int HttpStatusCode { get; set; }
        /// <summary>
        ///     Name of HTTP Status Code, like "InternalServerError"
        /// </summary>
        public string HttpStatusCodeName { get; set; }
        /// <summary>
        ///     OneTrueError error id
        /// </summary>
        public string ErrorId { get; set; }
    }

View per error

You can also create a Views\Errors folder in which you place files named as the http status code.

mvc5_views

They are automatically detected and used by the library.

Error controller

If you want to customize the error pages even further you can create your own ErrorController and place it in the Controller folder. It works just like any other controller. The only difference is that our library detect it and invoke it upon an error.

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        var model = RouteData.DataTokens["OneTrueModel"];
        return View("Error", model);
    }
}

You can of course use your own view model if you want to.

We also support action methods for different HTTP errors:

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        var model = RouteData.DataTokens["OneTrueModel"];
        return View("Error", model);
    }
    public ActionResult NotFound()
    {
        var model = RouteData.DataTokens["OneTrueModel"];
        return View(model);
    }
    public ActionResult InternalServerError()
    {
        var model = RouteData.DataTokens["OneTrueModel"];
        return View(model);
    }
    
}

Error pages

We have a set of default pages that are used unless you create your own. These will always be returned with the appropriate http status code.

Do note that if the accept type is JSON or XML we’ll return the error pages in those formats instead.

Not found

The requested URL (or internal resource) could not be found.

not_found

Currently, this page will be used if the exception is:

  • HttpException with status code 404
  • ObjectNotFoundException (Entity Framework)

Unauthorized

Unauthorized means that the must login to be able to access the requested page.

Unauthorized

This page will be used if the exception is:

  • HttpException with status code 401
  • UnauthorizedAccessException

Forbidden

Forbidden means that the user have logged in, but do not have enough privileges to access the requested page.

Forbidden-268x300

This page will be used if the exception is:

  • HttpException with status code 403
  • SecurityException

Fallback page

If none of the above conditions apply we’ll display the following error page.

InternalServerError

Dashboard

You will of course get all the usual features of OneTrueError like the dashboard

dashboard

Reference: Easier error handling in ASP.NET MVC5 from our NCG partner Jonas Gauffin at the jgauffin’s coding den blog.

Related Articles

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button