GraphQL responses can be partly successful, and clients must handle that correctly.
A GraphQL response can contain both data and errors. Each error has a message, usually locations and a path to the field that failed, plus optional extensions for machine-readable codes (e.g. {"code": "FORBIDDEN"}).
When a resolver throws, the executor records an error and sets that field to null. If the field is nullable, the rest of the response survives. If it is non-null, the null propagates to the nearest nullable parent, erasing the siblings too; if nothing is nullable all the way up, data itself becomes null.
That is why nullability is a design decision:
- Nullable fields isolate failures (a broken recommendations service does not kill the page).
- Non-null fields simplify client code but widen the blast radius of an error.
Two categories of errors:
- Request errors (syntax, validation, bad variables): nothing executes; the response has
errorsand nodatakey. - Field errors during execution: partial data plus
errors.
For expected domain outcomes ("email taken", "not found"), many teams return typed results instead, e.g. a union CreateUserResult = User | EmailTaken, so clients handle them with full type safety. Do not leak stack traces or internal messages: mask unexpected errors in production.
Example
import { buildSchema, graphql } from "graphql";
const schema = buildSchema(`
type Profile { name: String! recommendations: [String!] }
type Query { me: Profile }
`);
const rootValue = {
me: () => ({
name: "Ann",
recommendations: () => { throw new Error("recs service down"); },
}),
};
const res = await graphql({ schema, rootValue, source: "{ me { name recommendations } }" });
console.log(JSON.stringify(res.data));
// {"me":{"name":"Ann","recommendations":null}}
console.log(res.errors[0].message, res.errors[0].path);
// recs service down [ 'me', 'recommendations' ]Remember
- Errors carry message, locations, path and optional extensions
- A null in a non-null field bubbles up to the nearest nullable parent
- Model expected outcomes as types; reserve
errorsfor failures
Watch out for
- Clients that ignore
errorswheneverdatais present and silently show incomplete screens.