Skip to content

Error Handling in GraphQL

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Error Handling in Graphql. We cover key concepts, practical examples, and best practices to help you master this topic.

GraphQL error handling differs from REST. Instead of HTTP status codes, GraphQL returns a 200 status with an errors array in the response body. Business logic errors should be modeled in the schema as UserError types or union return types.

What You'll Learn

  • The errors array in GraphQL responses
  • UserError pattern for business rule errors
  • Custom error formatting and error codes
  • Partial responses with data and errors
  • Union-based error handling

Why It Matters

Proper error handling makes APIs debuggable and client-friendly. The UserError pattern lets clients display actionable messages. Custom error codes enable automated error handling in client applications.

Real-World Use

Shopify's GraphQL API returns userErrors on every mutation payload. GitHub returns a standardized error structure with type, message, and path fields for each error.

flowchart TD
    Request[Client Request] --> Resolver[Resolver]
    Resolver --> Success{Success?}
    Success -->|Yes| Data[Return Data]
    Success -->|No| Error{Error Type}
    Error -->|Validation| UserError[UserError in Payload]
    Error -->|Auth| AuthError[Authentication Error]
    Error -->|Server| ServerError[Internal Server Error]
    Data --> Response[Response: { data, errors }]
    UserError --> Response

Teacher Mindset

Distinguish between client errors (validation, auth) and server errors (database, network). Model client errors in the schema using UserError types. Let server errors appear in the errors array with error codes.

Code Examples

# Example 1: UserError in mutation payload
type UserError {
  field: String
  message: String!
  code: ErrorCode!
}

enum ErrorCode {
  VALIDATION_ERROR
  NOT_FOUND
  UNAUTHORIZED
  FORBIDDEN
  INTERNAL_ERROR
}

type BookMutationResponse {
  success: Boolean!
  book: Book
  errors: [UserError!]
}
// Example 2: Custom error formatting in Apollo Server
const server = new ApolloServer({
  typeDefs,
  resolvers,
  formatError: (formattedError) => {
    return {
      message: formattedError.message,
      code: formattedError.extensions?.code || 'INTERNAL_ERROR',
      path: formattedError.path,
      extensions: {
        timestamp: new Date().toISOString()
      }
    };
  }
});
// Example 3: Union-based error handling
type Mutation {
  createBook(input: CreateBookInput!): CreateBookResult!
}

union CreateBookResult = BookCreateSuccess | BookCreateError

type BookCreateSuccess {
  book: Book!
}

type BookCreateError {
  errors: [UserError!]!
}

Common Mistakes

  • Using HTTP status codes in GraphQL responses
  • Throwing errors for validation issues instead of returning UserError objects
  • Not including error codes for automated handling
  • Exposing internal stack traces in production
  • Returning null for entire response when one field fails

Practice

  1. Create a UserError type for mutation responses in your schema.
  2. Implement formatError to include custom error codes.
  3. Return partial data with errors for a query that has one failing resolver.
  4. Design a mutation that returns a union of success and error types.
  5. Challenge: Implement a validation system that returns multiple field errors from a single mutation.

FAQ

How does GraphQL handle partial errors?

GraphQL returns both data and errors in the response. Successful fields resolve normally while failed fields have null values with error entries.

What is the UserError pattern?

The UserError pattern returns a list of user-friendly errors in the mutation payload instead of throwing exceptions. Clients display these errors directly.

Should I use throw or return errors for validation?

Return structured UserError objects in the payload for validation errors. Throw only for unexpected server errors.

How do I add error codes?

Include a code field in your UserError type or set extensions.code in formatError for automatic errors.

Can I use unions for error handling?

Yes. Union types let the mutation return either a success object or an error object, making the response type explicit.

Mini Project

Add structured error handling to all your e-commerce mutations. Create a UserError type, define error codes, and implement both payload-based and union-based error patterns.

What's Next

Next, you will learn about authentication strategies for securing GraphQL APIs.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro