Setting the file. One moment.
Subchapter 11.1
references/errors.mdMarkdown7 KBView on GitHub
This reference covers error handling patterns in GraphQL schema design.
GraphQL has a built-in error system with errors in the response:
{
"data": { "user": null },
"errors": [
{
"message": "User not found",
"path": ["user"],
"extensions": {
"code": "NOT_FOUND"
}
}
]
}| Scenario | Pattern |
|---|---|
| Unexpected server error | Built-in errors |
| Authentication required | Built-in errors |
| User input validation | Union result types |
| Business rule violation | Union result types |
| Partial success possible | Union or nullable fields |
| Multiple error types | Union result types |
type Mutation {
createUser(input: CreateUserInput!): CreateUserResult!
}
union CreateUserResult = CreateUserSuccess | ValidationError
type CreateUserSuccess {
user: User!
}
type ValidationError {
message: String!
field: String
}union CreateOrderResult =
| CreateOrderSuccess
| ValidationError
| InsufficientInventory
| PaymentFailed
type CreateOrderSuccess {
order: Order!
}
type ValidationError {
message: String!
field: String
}
type InsufficientInventory {
message: String!
unavailableItems: [OrderItem!]!
}
type PaymentFailed {
message: String!
reason: PaymentFailureReason!
retryable: Boolean!
}
enum PaymentFailureReason {
CARD_DECLINED
INSUFFICIENT_FUNDS
EXPIRED_CARD
FRAUD_SUSPECTED
}mutation CreateOrder($input: CreateOrderInput!) {
createOrder(input: $input) {
... on CreateOrderSuccess {
order {
id
total
}
}
... on ValidationError {
message
field
}
... on InsufficientInventory {
message
unavailableItems {
productId
requestedQuantity
availableQuantity
}
}
... on PaymentFailed {
message
reason
retryable
}
}
}interface Error {
message: String!
}
type ValidationError implements Error {
message: String!
field: String!
}
type NotFoundError implements Error {
message: String!
resourceType: String!
resourceId: ID!
}
type PermissionError implements Error {
message: String!
requiredPermission: String!
}
union UpdateUserResult = User | ValidationError | NotFoundError | PermissionErrortype Query {
user(id: ID!): UserResult!
}
union UserResult = User | NotFoundError | PermissionError
# Client query:
query GetUser($id: ID!) {
user(id: $id) {
... on User {
id
name
}
... on Error {
message
}
}
}enum ErrorCode {
# Validation errors
VALIDATION_FAILED
INVALID_INPUT
REQUIRED_FIELD_MISSING
# Authentication/Authorization
UNAUTHENTICATED
UNAUTHORIZED
TOKEN_EXPIRED
# Resource errors
NOT_FOUND
ALREADY_EXISTS
CONFLICT
# Business logic
INSUFFICIENT_FUNDS
LIMIT_EXCEEDED
OPERATION_NOT_ALLOWED
# System errors
INTERNAL_ERROR
SERVICE_UNAVAILABLE
RATE_LIMITED
}
type MutationError {
code: ErrorCode!
message: String!
field: String
details: JSON
}type ValidationError {
code: ErrorCode!
message: String!
field: String
}
type CreateUserSuccess {
user: User!
}
union CreateUserResult = CreateUserSuccess | ValidationError
# Usage enables consistent error handling:
# if (result.__typename === 'ValidationError') {
# switch (result.code) {
# case 'ALREADY_EXISTS': ...
# case 'INVALID_INPUT': ...
# }
# }For operations on multiple items:
input BulkUpdateInput {
items: [UpdateItemInput!]!
}
type BulkUpdateResult {
successful: [Item!]!
failed: [BulkUpdateError!]!
}
type BulkUpdateError {
index: Int!
itemId: ID
error: UpdateError!
}
union UpdateError = ValidationError | NotFoundError | PermissionError
type Mutation {
bulkUpdateItems(input: BulkUpdateInput!): BulkUpdateResult!
}mutation BulkUpdate($input: BulkUpdateInput!) {
bulkUpdateItems(input: $input) {
successful {
id
name
}
failed {
index
itemId
error {
... on ValidationError {
message
field
}
... on NotFoundError {
message
resourceId
}
}
}
}
}Return success with warnings:
type ImportResult {
imported: [Record!]!
skipped: [SkippedRecord!]!
warnings: [ImportWarning!]!
}
type SkippedRecord {
row: Int!
reason: String!
data: JSON
}
type ImportWarning {
row: Int
message: String!
severity: WarningSeverity!
}
enum WarningSeverity {
INFO
WARNING
ERROR
}type UserWithExternalData {
id: ID!
name: String!
# These might fail independently
profileImage: Image # External service
socialConnections: [Social] # External service
# Errors for each
profileImageError: String
socialConnectionsError: String
}Alternative with explicit result types:
type UserWithExternalData {
id: ID!
name: String!
profileImage: ImageResult!
socialConnections: SocialConnectionsResult!
}
union ImageResult = Image | FetchError
union SocialConnectionsResult = SocialConnectionList | FetchError
type FetchError {
message: String!
service: String!
retryable: Boolean!
}