GraphQL error handling
Two types of error
| Type | Where it appears | When it is used |
|---|---|---|
userErrors | In the mutation payload | Validation and business logic errors |
errors (GraphQL) | At the top of the response | Structural 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:
| Situation | Error type |
|---|---|
| Resource not found in a query | GraphqlNotFound |
| Invalid or missing token | authentication error |
| Insufficient permissions | authorization error |
| Malformed query | parsing 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;
}
Recommended pattern
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;
}