Skip to main content

GraphQL error handling

Two types of error​

TypeWhere it appearsWhen it is used
userErrorsIn the mutation payloadValidation and business logic errors
errors (GraphQL)At the top of the responseStructural errors, resource not found, permissions

1. userErrors - validation errors​

Every mutation returns a userErrors field: null on success, otherwise the list of errors.

Structure:

type UserError {
code: ErrorCode!
field: String # specific field that caused the error, if applicable
message: String # human-readable description
}

enum ErrorCode {
BAD_INPUT # invalid or missing input
NOT_FOUND # resource not found
NOT_UNIQUE # uniqueness violation
PROTECTED # deletion blocked by dependencies
}

Example error response:

{
"data": {
"supporterCreate": {
"supporter": null,
"userErrors": [
{
"code": "BAD_INPUT",
"field": "email",
"message": "This field is required."
}
]
}
}
}

Example success response:

{
"data": {
"supporterCreate": {
"supporter": {
"id": 42,
"email": "mario@example.com"
},
"userErrors": null
}
}
}

How to handle userErrors​

Check userErrors before using the returned data:

const { data } = await client.mutate({ mutation: CREATE_SUPPORTER, variables });

if (data.supporterCreate.userErrors?.length) {
const errors = data.supporterCreate.userErrors;
// handle errors per field
errors.forEach(err => {
console.error(`[${err.code}] ${err.field}: ${err.message}`);
});
return;
}

const supporter = data.supporterCreate.supporter;

2. GraphQL errors - structural exceptions​

Other errors arrive in the errors array of the response, as standard GraphQL errors.

Common cases:

SituationError type
Resource not found in a queryGraphqlNotFound
Invalid or missing tokenauthentication error
Insufficient permissionsauthorization error
Malformed queryparsing error

Example response:

{
"data": null,
"errors": [
{
"message": "Resource not found",
"locations": [{ "line": 2, "column": 3 }],
"path": ["donation"]
}
]
}
note

The HTTP status is almost always 200 even with GraphQL errors: check the errors field.

How to handle GraphQL errors​

const response = await client.query({ query: GET_DONATION, variables: { id: 999 } });

if (response.errors?.length) {
const message = response.errors[0].message;
// e.g. "Resource not found"
console.error('GraphQL error:', message);
return;
}
async function safeMutate(client, mutation, variables) {
let response;

try {
response = await client.mutate({ mutation, variables });
} catch (networkError) {
// Network error or HTTP 5xx
throw new Error('Network error: ' + networkError.message);
}

// Structural GraphQL errors
if (response.errors?.length) {
throw new Error('GraphQL error: ' + response.errors[0].message);
}

// Business logic errors in the mutation
const rootKey = Object.keys(response.data)[0];
const result = response.data[rootKey];

if (result.userErrors?.length) {
throw new Error('Validation error: ' + result.userErrors[0].message);
}

return result;
}