Creating a URL shortener using ASP.NET WepAPI and MVC: error handling

In the two previous post I discussed about the first step to creare this application and the implementation of the business logic. Now we can implement the error handling.

We have two custom exception classes:

  • ShorturlConflictException (when a segment already exists) and
  • ShorturlNotFoundException (when a segment isn’t found in the database).

There is also a third type: an unexpected exception, for example when there is no database connection. Normally, the user will see these errors. We have to build a mechanism where these exceptions are caught and a nice error page is shown, corresponding to the type of error, with the corresponding HTTP status code.

We need to add a filter to the Web project. Add a new folder called “Filters” and add a “ShorturlExceptionFilter” class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using PSC.Shorturl.Web.Exceptions;

namespace PSC.Shorturl.Web.Filters
{
    public class ShorturlErrorFilter : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            HttpStatusCode code = HttpStatusCode.InternalServerError;
            var ex = filterContext.Exception;
            string viewName = "Error500";

            if (ex is ShorturlNotFoundException)
            {
                code = HttpStatusCode.NotFound;
                viewName = "Error404";
            }
            if (ex is ShorturlConflictException)
            {
                code = HttpStatusCode.Conflict;
                viewName = "Error409";
            }

            filterContext.Result = new ViewResult()
            {
                ViewName = viewName
            };

            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = (int)code;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

This filter extends from the HandleErrorAttribute, and overrides the OnException method. In this method we do our own exception handling. If the exception is one of our own exceptions, a 404 or 409 is returned, else a 500 is returned. At the bottom of the method we tell the context that the exception is handled, and the current response (the ugly error page) will be cleared and our custom views (which are defined below) will be returned.

Add the following views in the “Views\Shared” folder:

Error404.cshtml

@{
    ViewBag.Title = "Not Found";
}

<h2>Not Found</h2>

<p>The resource you've requested isn't found.</p>

Error409.cshtml

@{
    ViewBag.Title = "Conflict";
}

<h2>Conflict</h2>

<p>The name you've chosen already exists.</p>

Error500.cshtml

@{
    ViewBag.Title = "Error";
}

<h2>Error</h2>

<p>An unexpected error occured.</p>

The only thing we have to do now is add the filter to our FilterConfig class (under App_Start). In the FilterConfig class, replace the existing method with this method:

using System.Web;
using System.Web.Mvc;
using PSC.Shorturl.Web.Filters;

namespace PSC.Shorturl.Web
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new ShorturlErrorFilter());
            filters.Add(new HandleErrorAttribute());
        }
    }
}

Now, when there is an exception, a nice error page will be shown. Next post about WebApi integration.

Leave a Reply

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