Skip to content

CONCEPT Cited by 1 source

GraphQL error extensions

Definition

GraphQL error extensions are an open-ended metadata channel on each error object in the response.errors array. The base envelope GraphQL guarantees is fixed:

{ "message": "Something happened", "path": ["foo", "bar"] }

extensions is an officially sanctioned field where the server may attach arbitrary structured metadata without extending the core envelope:

{
  "message": "Not Found",
  "extensions": { "code": "NOT_FOUND" }
}

Why it exists

GraphQL clients typed the data field from the schema have no schema-derived type for errors. Without extensions, the only discriminating field is message — and "parsing the message is a no-go because it is not reliable" (Source: sources/2021-04-12-zalando-modeling-errors-in-graphql). extensions closes that gap by letting the server ship a machine-readable code (e.g. NOT_FOUND, NOT_AUTHORIZED, INTERNAL_SERVER_ERROR) plus any per-error structured metadata.

The extensions.code convention

The widely adopted convention — codified in Apollo Server defaults and in Zalando's post — is to put an error code string in extensions.code. Clients switch on the code, not the message:

code value Front-end action
NOT_FOUND show 404 page
NOT_AUTHORIZED show login dialog
INTERNAL_SERVER_ERROR retry / show generic error UI
INVALID_EMAIL highlight input field red

Structured metadata beyond code

Before Zalando reached for schema-level Problem types, they first tried pushing richer structured metadata into extensions:

{
  "errors": [{
    "message": "Multiple inputs are invalid",
    "extensions": {
      "invalidInputs": [
        { "code": "INVALID_EMAIL",    "message": "..." },
        { "code": "INVALID_PASSWORD", "message": "..." }
      ]
    }
  }]
}

This is legal and works, but the payload is not discoverable from the GraphQL schema — which is what motivated the move to schema-modeled Problem types for mutation input validation.

Where extensions stops being enough

  • When clients need the error shape to show up in codegen output.
  • When multiple locales of a customer-facing message need to travel inside the error.
  • When the error must carry nested, typed domain data (e.g. per-field validation failures).

At that point Zalando recommends moving the error into the schema as a Problem type on a union ...Result, while keeping bugs and developer-actionable errors in extensions.

Seen in

Last updated · 476 distilled / 1,218 read