Error Handling

GraphQL gives you two complementary ways to communicate errors to clients: the top-level errors array for exceptional failures, and errors-as-data for expected, domain-specific failures. Using the right approach for each situation keeps your API predictable and makes error states discoverable through the schema.

Use top-level errors for exceptional failures

The standard GraphQL errors array handles infrastructure and system failures:

{
  "data": null,
  "errors": [{
    "message": "Database connection failed",
    "extensions": {
      "code": "INTERNAL_SERVER_ERROR"
    }
  }]
}

Use errors-as-data for domain errors

Business logic errors belong in the schema as structured types:

type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
}
 
type CreateUserPayload {
  user: User
  userErrors: [UserError!]!
}
 
type UserError {
  message: String!
  field: [String!]
  code: UserErrorCode!
}
 
enum UserErrorCode {
  USERNAME_TAKEN
  INVALID_EMAIL
  PASSWORD_TOO_SHORT
}

This pattern makes errors discoverable through introspection and provides type safety.

Choose based on whether errors are exceptional

Error typePatternExample
Infrastructure failureTop-level errorDatabase timeout, network error
Invalid GraphQLTop-level errorSyntax error, unknown field
Authentication requiredTop-level errorMissing auth token
Business rule violationerrors-as-dataUsername taken, invalid email
Validation failureerrors-as-dataRequired field missing
Domain constrainterrors-as-dataInsufficient inventory

next lesson

Global Object Identification

Use globally unique IDs and the Node interface to enable caching, refetching, and efficient schema traversal.

Go to next lesson