Error Handling in GraphQL
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
- Create a UserError type for mutation responses in your schema.
- Implement formatError to include custom error codes.
- Return partial data with errors for a query that has one failing resolver.
- Design a mutation that returns a union of success and error types.
- Challenge: Implement a validation system that returns multiple field errors from a single mutation.
FAQ
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