Pattern: Error Report

How can an API provider inform its clients about communication and processing faults? How can this information be made independent of the underlying communication technologies and platforms (for example, protocol-level headers representing status codes)?


The final version of this pattern is featured in our book Patterns for API Design: Simplifying Integration with Loosely Coupled Message Exchanges.

Pattern: Error Report

a.k.a. API Fault Management, Error Code and Message, Error Report

Context

Communication participants have to manage unexpected situations at runtime reliably. For instance, a client has made an API call, but the API server is not able to process this request successfully. The failure could be caused by incorrect request data, invalid server state, missing access rights, or numerous other problems that could be the fault of the client, the provider and its backend implementation, or the underlying communications infrastructure.

Problem

How can an API provider inform its clients about communication and processing faults? How can this information be made independent of the underlying communication technologies and platforms (for example, protocol-level headers representing status codes)?

Forces

The following conflicting concerns make error reporting challenging to design:

  • Expressiveness and target audience expectations
  • Robustness and reliability
  • Security and performance
  • Interoperability and portability
  • Internationalization

Pattern forces are explained in depth in the book.

Solution

Reply with error codes in response messages that indicate and classify the faults in a simple, machine-readable way. In addition, add textual descriptions of the errors for the API client stakeholders, including developers and/or end users such as administrators.

Sketch

A solution sketch for this pattern from pre-book times is:

Example

Customers logging in to their Lakeside Mutual accounts have to provide their user name and password:

curl -i  -X POST \
  --header "Content-Type: application/json" \
  --data '{"username":"xyz","password":"wrong"}' \
  http://localhost:8080/auth

If these are not correct, an HTTP 401 error is returned along with a more detailed response, both assembled by the Spring framework in this example:

HTTP/1.1 401 
Content-Type: application/json;charset=UTF-8
Date: Wed, 20 Jun 2018 08:25:10 GMT

{
  "timestamp" : "2018-06-20T08:25:10.212+0000",
  "status" : 401,
  "error" : "Unauthorized",
  "message" : "Access Denied",
  "path" : "/auth"
}

Similarly, consider the client does not specify the content type of the request body:

curl -i -X POST \
  --data '{"username":"xyz","password":"wrong"}' \
  http://localhost:8080/auth          

Then the provider will answer with an appropriate error message (again using the Spring defaults):

HTTP/1.1 415 
EHDate: Wed, 20 Jun 2018 08:29:09 GMT

{
  "timestamp" : "2018-06-20T08:29:09.452+0000",
  "status" : 415,
  "error" : "Unsupported Media Type",
  "message" : "Content type 
      'application/x-www-form-urlencoded;
       charset=UTF-8' not supported",
  "path" : "/auth"
}

The message tells the developer that the (default) content type of application/x-www-form-urlencoded is not supported by this endpoint. The Spring framework allows to customize the default error reporting, see Custom Error Message Handling for REST API.

Are you missing implementation hints? Our papers publications provide them (for selected patterns).

Consequences

The resolution of pattern forces and other consequences are discussed in our book.

Known Uses

RFC 7807 proposes a standard format for machine-readable error details for HTTP APIs. In addition to using the HTTP status code, the response body contains an Atomic Parameter List providing information about the type of error that occurred (in the form of an URI), a title describing the problem category and a detail element with a more elaborate problem description that includes data of the request. For example:

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
  "type": "https://myshop.org/out-of-stock",
  "title": "Out of Stock",
  "status": 400,
  "detail": "Item C330 is out of stock"
}

For a more detailed discussion on how to implement RFC 7807 in the Spring ecosystem, see this blog post from Codecentric.

The JSON API specification recommends a very similar error response structure. It mandates that the response is an Atomic Parameter Tree with a single errors root that contains further details. For example, the above example would be represented as follows.1

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  "errors": {
    "links": {
      "about": "https://myshop.org/out-of-stock"
    },
    "title": "Out of Stock",
    "status": "400",
    "detail": "Item C330 is out of stock"  
  }
}

Error Reporting can also be found in many public web APIs, but their level of detail often differs:

  • Twitter makes heavy use of HTTP error codes with details in the payload such as: {"errors":[{"message":"Sorry, that page does not exist","code":34}]}.
  • The Facebook Graph API similarly returns an error object. An additional debug parameter passed in the query string adds further information to the response.
{
  "error": {
    "message": "(#100) Tried accessing nonexisting field 
    (names) on node type (Event)",
    "type": "OAuthException",
    "code": 100,
    "fbtrace_id": "Dv4/M3V0XMv"
  }
}
  • Atlassian’s JIRA Cloud API uses a similar approach and returns a response body in addition to the status code in its error responses (which are defined in a JSON schema).
  • The Microsoft Graph API defines many API-specific error codes, for example an maxQueryLengthExceeded error.
  • The error handling in the Kloudless APIs “unifies error responses into a common format prior to propagating them to your application”.
  • A dynamic interface integration solution for core banking (Brandner et al. (2004)) has a rather elaborate approach to Error Reporting: application-level error objects travel as part of a standard Context Representation present in all API calls that also contains other Metadata Elements. These error objects are standardized across the API via XML Schema.

The Pattern Adoption Story: Dutch Government & Energy Sector contributed by a reader has more known uses and further discussion of this pattern.

More Information

Related Patterns

Error Reporting can be part of the Context Representation in response messages. It may contain Metadata Elements to learn about next possible steps (to work around the reported problem or to correct it).

The Remoting Error pattern by Voelter, Kircher, and Zdun (2004) contains a generalized and more low-level notion of this pattern focused on the viewpoint of distributed system middleware.

Error Reporting is an important building block in making API implementations robust and resilient. Many more patterns are required for a full solution, for instance Circuit Breakers first described in Nygard (2018). The systems management category in Hohpe and Woolf (2003) contains related patterns such as Dead Letter Channel.

Other Sources

See Chapter 4 of Sturgeon (2016) for detailed coverage of Error Reporting in the context of RESTful HTTP (implemented in PHP). Production readiness in general is covered in “Production-Ready Microservices: Building Standardized Systems Across an Engineering Organization” (Fowler 2016).

References

Brandner, Michael, Michael Craes, Frank Oellermann, and Olaf Zimmermann. 2004. “Web Services-Oriented Architecture in Production in the Finance Industry.” Informatik-Spektrum 27 (2): 136–45. https://doi.org/10.1007/s00287-004-0380-2.
Fowler, Susan J. 2016. Production-Ready Microservices: Building Standardized Systems Across an Engineering Organization. 1st ed. O’Reilly.
Hohpe, Gregor, and Bobby Woolf. 2003. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley.
Nygard, Michael. 2018. Release It! Design and Deploy Production-Ready Software. 2nd ed. Pragmatic Bookshelf.
Sturgeon, Phil. 2016. Build APIs You Won’t Hate. LeanPub. https://leanpub.com/build-apis-you-wont-hate.
Voelter, Markus, Michael Kircher, and Uwe Zdun. 2004. Remoting Patterns - Foundations of Enterprise, Internet, and Realtime Distributed Object Middleware. Wiley.


  1. Note that the examples show only a subset of possible fields, see the respective documentation for a full description of all fields. Also note that RFC 7807 requires status to be a number, and JSON-API suggests/expects a string.↩︎