Skip to main content
GraphQL provides a structured way to handle errors. Understanding error responses helps you build robust applications.

Error response structure

GraphQL responses always include a data field and may include an errors field:
{
  "data": {
    "deal": null
  },
  "errors": [
    {
      "message": "Deal not found",
      "path": ["deal"],
      "extensions": {
        "code": "NOT_FOUND"
      }
    }
  ]
}

Error types

Validation errors

Occur when your query doesn’t match the schema:
{
  "errors": [
    {
      "message": "Cannot query field 'invalidField' on type 'Deal'",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

Authentication errors

Occur when authentication fails:
{
  "errors": [
    {
      "message": "Unauthorized",
      "extensions": {
        "code": "UNAUTHENTICATED"
      }
    }
  ]
}

Business logic errors

Occur when operations fail due to business rules:
{
  "errors": [
    {
      "message": "Loan amount exceeds maximum",
      "path": ["createLoan"],
      "extensions": {
        "code": "VALIDATION_ERROR"
      }
    }
  ]
}

Handling errors in code

JavaScript/TypeScript example

async function fetchDeal(id: string) {
  const response = await fetch('/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      query: `
        query GetDeal($id: ID!) {
          deal(id: $id) {
            id
            status
          }
        }
      `,
      variables: { id }
    })
  });

  const result = await response.json();

  if (result.errors) {
    // Handle errors
    result.errors.forEach(error => {
      console.error('GraphQL Error:', error.message);
      
      if (error.extensions?.code === 'UNAUTHENTICATED') {
        // Handle authentication error
        redirectToLogin();
      } else if (error.extensions?.code === 'NOT_FOUND') {
        // Handle not found error
        showNotFoundMessage();
      }
    });
    return null;
  }

  return result.data.deal;
}

Partial data

GraphQL may return partial data even when some fields fail:
{
  "data": {
    "deal": {
      "id": "123",
      "status": "ACTIVE",
      "borrowers": null
    }
  },
  "errors": [
    {
      "message": "Failed to load borrowers",
      "path": ["deal", "borrowers"]
    }
  ]
}
Always check for both data and errors in your response handling.

Error extensions

Many errors include extension fields with additional context:
{
  "errors": [
    {
      "message": "Validation failed",
      "extensions": {
        "code": "VALIDATION_ERROR",
        "field": "loanAmount",
        "reason": "Amount exceeds maximum limit"
      }
    }
  ]
}

Best practices

  1. Always check for errors - Never assume a query succeeded
  2. Handle errors gracefully - Show user-friendly error messages
  3. Log errors for debugging - Include error details in logs
  4. Use error codes - Check extensions.code for specific error types
  5. Handle partial data - Some fields may be null even if query succeeds

Common error codes

  • UNAUTHENTICATED - Authentication required
  • FORBIDDEN - Insufficient permissions
  • NOT_FOUND - Resource doesn’t exist
  • VALIDATION_ERROR - Input validation failed
  • INTERNAL_ERROR - Server error