Jeremy Likness
Jeremy Likness
Empowering developers to be their best.
📅 Dec 7, 2017 🕘 3 min read 💬 636 words

Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 3: Exceptions

Setting Expectations for Exceptions

Part of the series: Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0

This is the third part in a multi-part series on Web API design. Here is the full list for easy navigation:

  1. Intro and Content Negotiation
  2. HATEOAS
  3. Exceptions (“x” marks the spot)
  4. Concurrency
  5. Security
  6. Bonus (because I said it would be five): Swagger

Without exception, you should handle exceptions consistently. Chew on that one for a minute. If you’ve been a programmer for more than a few seconds, you know the rule of thumb is to expect the unexpected. Exceptions are those nasty faults that happen when things don’t go as expected, but fortunately there are ways to deal with them and, in the case of APIs, handle them gracefully at the client.

Take, for instance, our example set of APIs that provide a “to do” list. ASP.NET Core is kind enough to keep your website and APIs up and running even after your code falls down, but the response it provides is about as useful as an 8-minute workout.

A Typical Exception

A Typical Exception

Fortunately, there’s a standard for dealing with this. Take a look at Microsoft’s REST API Guidelines. The section for response codes provides some detail around a standard way to send errors back to the client. Although you can handle these globally by leveraging the various error handling features available to ASP.NET Core apps, sometimes you may want fine-grained control over exceptions to return custom information and massage the data to avoid leaking sensitive information.

The example app handles exceptions by providing a generic ExceptionHelper class to assist with processing errors (because “help with exceptions” seemed redundant). Although the example does this is in a generic fashion to keep the demo simple, a production app might inspect the type of the exception and format the response differently based on known exception types such as data exceptions, security exceptions, etc.

public static class ExceptionHelper
{
    public static object ProcessError(Exception ex)
    {
        return new {
            error = new {
                code = ex.HResult,
                message = ex.Message
            }
        };
    }
}

For some reason I tend to write perfect code all of the time (if you believe that, DM me on Twitter about the timeshare I have for sale), so I had to “force an error” to get my app to crash. For this demo, I plucked a completely random number right out of the air to throw an exception when it’s referenced.

if (id == 8675309) 
{
    throw new Exception("Bad digits.");
}

This, of course, is in a try ... catch block. When the exception is caught, it uses the standard “bad request” status code to return an error object.

catch(Exception ex)
{
    return new BadRequestObjectResult(ExceptionHelper.ProcessError(ex));
}

Remember, this is a simple demonstration. The link I shared earlier in the article explains how to handle uncaught exceptions globally in case you always use the same strategy and don’t want to pepper your code with tries and catches.

The next time our server takes exception to what we ask of it, instead of an unhelpful 500 error (that should only get thrown for truly unanticipated server mishaps) we get a more refined 400 error along with details.

An Exceptional Exception

An Exceptional Exception

Even better news: if you’re held in the thrall of one of today’s myriad JavaScript front end frameworks like Angular, React, or Vue (I had to list those for SEO), most of them have the concept of a global interceptor that can handle response codes from HTTP requests. That allows you to build a standard error handling component that deals with requests in a consistent fashion. Now you have something more exciting to do than figure out modal dialogues and spinners.

I mentioned spinners, right?

I mentioned spinners, right?

That’s not all, folks … there’s more to this series!

Easy navigation:

  1. Intro and Content Negotiation
  2. HATEOAS
  3. Exceptions (“x” marks the spot)
  4. Concurrency
  5. Security
  6. Bonus (because I said it would be five): Swagger

Regards,

Jeremy Likness

Part of the series: Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0

  1. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 1: Content Negotiation
  2. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 2: HATEOAS
  3. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 3: Exceptions
  4. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 4: Optimistic Concurrency
  5. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Part 5: Security
  6. Five RESTFul Web Design Patterns Implemented in ASP.NET Core 2.0 Bonus: Swagger
 
 
comments powered by Disqus