Error handling

Problem Details

Problem Details for HTTP APIs (RFC 7807) defines a simple JSON format to convey additional information about an error to an API consumer. This information complements the HTTP status codes [RFC7231].

For any problem occurred during processing, whether it be caused by the client or the server, the API provider supplies

  1. a suitable [status code](#Status codes): 4xx for consumer or 5xx for server errors

  2. a RFC 7807 problem detail message

Problem Details JSON schema (from problem-v1.yaml)

    Problem:
      description: A Problem Details object (RFC 7807)
      type: object
      properties:
        type:
          type: string
          format: uri
          description: An absolute URI that identifies the problem type
          default: about:blank  # kept for backwards-compatibility, type will be mandatory in problem-v2
        href:
          type: string
          format: uri
          description: An absolute URI that, when dereferenced, provides human-readable documentation for the problem type (e.g. using HTML).
        title:
          type: string
          description: A short, summary of the problem type. Written in English and readable for engineers (usually not suited for non technical stakeholders and not localized).
          example: Service Unavailable
        status:
          type: integer
          format: int32
          description: The HTTP status code generated by the origin server for this occurrence of the problem.
          minimum: 400
          maximum: 600
          exclusiveMaximum: true
          example: 503
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence of the problem
        instance:
          type: string
          format: uri
          description: An absolute URI that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.

Any information on a problem SHOULD be provided in the Problem Detail format, as specified in Problem Details for HTTP APIs (RFC 7807):

  • the media type for problems SHOULD be application/problem+json

  • status: the HTTP status code

  • type: a unique identifier for the type of the problem that MUST remain stable over time. It can be used by API clients during problem handling.

  • title: a short summary of the problem type in English

  • instance: a unique identifier of the problem instance. It could be used to track the message for support purposes.

  • detail: consumer-friendly information about the specific failing request. It MAY be localized using language negotiation.

  • additional properties may be added to provide more information on the problem

The Problem Details response body MAY be absent when the HTTP status code itself provides sufficient information (e.g. for 405 Method Not Allowed, 406 Not Acceptable or 415 Unsupported Media Type).

This guide applies following additional restrictions on the Problem Details structure:

  • type and instance SHOULD be specified as absolute URIs in order to avoid issues when resolving relative URIs (see ???)

  • The type property, a stable identifier for the type of problem, is MANDATORY instead of optional

  • a new optional href property SHOULD be used to provide a URI to human-readable documentation on the problem type instead of dereferencing the type value

Note that using href instead of type for documentation intentionally deviates from the recommendation in the RFC. href allows use of a URL for documentation purposes that may change over time, while type can be specified as a URN that must remain stable. This is especially useful for API-specific problem types for which the documentation URL may depend on technical aspects, like deployment environment.

POST /enterprises/0206731645/employers
{
    "name": "John"
}

HTTP/1.1 404 Not Found
Content-Type: application/problem+json
BelGov-Trace-Id: d9e35127-e9b1-4201-a211-2b52e52508df
{
  "type": "urn:problem-type:resourceNotFound",
  "href": "https://example.com/specification/rest/api-guide/problems/resourceNotFound.html",
  "instance": "urn:uuid:d9e35127-e9b1-4201-a211-2b52e52508df",
  "status": 404,
  "title": "Resource is not found",
  "detail": "There is no enterprise in CBE with enterprise number 0206731645",
  "issues": [
      {
        "in": "path",
        "name": "enterpriseNumber",
        "detail": "the enterprise number is not assigned",
        "value": "0206731645"
      }
  ]
}

Problem type SHOULD be specified as a URN in one of following formats:

  • urn:problem-type:<org>:<api>:<type>

  • urn:problem-type:<org>:<type>

with:

  • <org>: a short identifier for the organization

  • <api>: name of the API. It MAY be used for API-specific problem types

  • <type>: type of the problem in lowerCamelCase

A description of an API-specific problem type MAY be provided as a reference data resource : /refData/problemTypes/{problemType}. If provided, at least the HTML media type SHOULD be supported.

Reverse FQDN notation for <org> is not recommended in order to keep the identifiers short and readable.

{
  "type": "urn:problem-type:cbss:socialStatus:searchCriteriaTooWide",
  "href": "https://api.ksz-bcss.fgov.be/socialStatus/v2/refData/problemTypes/urn:problem-type:cbss:socialStatus:searchCriteriaTooWide",
  "status": 400,
  "title": "Search criteria should be more specific",
  "detail": "Only one search parameter specified. Please specify at least two.",
  "instance": "urn:uuid:123e4567-e89b-12d3-a456-426614174000"
}

A problem MUST NOT leak sensitive implementation and infrastructure details. Providers must strip this information (e.g. DB error codes, internal hostnames, stacktraces) before returning the problem detail to the consumer.

E.g. this should not be returned to a client:

HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: application/problem+json
{
  "type": "urn:problem-type:internalServerError",
  "instance": "urn:uuid:ac19acc6-5e11-4b2a-8c10-f9680998d07a",
  "title": "Internal Server Error",
  "detail": "Unexpected error code 24879 in server product XYZ v1.0.1",
  "stackTrace": [  [
      "EJBException: java.lang.RuntimeException: Something horrible happened on the server",
      "org.jboss.as.ejb3.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:191)",
      "org.jboss.as.ejb3.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:282)",
      "org.jboss.as.ejb3.CMTTxInterceptor.required(CMTTxInterceptor.java:345)",
      "org.jboss.as.ejb3.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:243)"
    ],
    [
      "Caused by: java.lang.RuntimeException: Something horrible has happened on the server",
      "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
      "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)",
      "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
      "java.lang.reflect.Method.invoke(Method.java:606)"
    ]
  ]
}

Problem types that may occur on all or most operations of an API (e.g. a missing permission, an internal server error, request violates schema, …​) SHOULD NOT each be documented explicitly in its OpenAPI specification, as this would clutter the spec and make it difficult to keep up to date.

Rather, a default Problem response SHOULD be added to each operation. Operation-specific problem types should still be documented.

Specifying a default problem response ensures compatibility with clients that perform strict OpenAPI validation on response messages.

/orders/{orderId}/archive:
  post:
    summary: archive the order
    operationId: archiveOrder
    parameters:
    - "$ref": "#/components/schemas/OrderId"
    responses:
      "200":
        "$ref": "#/components/responses/OrderArchivedResponse"
      "409":
        description: Order can not be archived when it's not completed
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/InvalidStateProblem"
      default:
        "$ref": "./problem/v1/problem-v1.yaml#/components/responses/ProblemResponse"