Skip to content

API Error Handling Guidelines

Table of Contents

  1. Error Response Format
  2. HTTP Status Codes
  3. Error Types
  4. Validation Errors
  5. Authentication & Authorization
  6. Rate Limiting
  7. Error Logging
  8. Client-Side Handling

Error Response Format

Standard Error Response

{
  "error": {
    "code": "INVALID_INPUT",
    "message": "One or more validation errors occurred.",
    "target": "user_registration",
    "details": [
      {
        "code": "REQUIRED_FIELD",
        "target": "email",
        "message": "Email is required"
      },
      {
        "code": "INVALID_FORMAT",
        "target": "password",
        "message": "Password must be at least 8 characters"
      }
    ],
    "innerError": {
      "code": "VALIDATION_ERROR",
      "requestId": "a1b2c3d4",
      "timestamp": "2025-06-30T06:27:45Z"
    }
  }
}

HTTP Status Codes

2xx Success

  • 200 OK: Standard success response
  • 201 Created: Resource created successfully
  • 202 Accepted: Request accepted for processing
  • 204 No Content: Success with no content to return

4xx Client Errors

  • 400 Bad Request: Invalid request format
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Insufficient permissions
  • 404 Not Found: Resource doesn't exist
  • 405 Method Not Allowed: HTTP method not supported
  • 406 Not Acceptable: Requested format not available
  • 409 Conflict: Resource conflict
  • 410 Gone: Resource permanently removed
  • 422 Unprocessable Entity: Validation errors
  • 429 Too Many Requests: Rate limit exceeded

5xx Server Errors

  • 500 Internal Server Error: Generic server error
  • 501 Not Implemented: Feature not implemented
  • 502 Bad Gateway: Invalid response from upstream
  • 503 Service Unavailable: Service temporarily unavailable
  • 504 Gateway Timeout: Upstream timeout

Error Types

Standard Error Codes

Code Description
AUTH_REQUIRED Authentication required
FORBIDDEN Insufficient permissions
INVALID_INPUT Invalid request data
NOT_FOUND Resource not found
RATE_LIMIT_EXCEEDED Too many requests
RESOURCE_EXISTS Resource already exists
SERVICE_ERROR Internal server error
VALIDATION_ERROR Data validation failed

Validation Errors

Request Validation

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "code": "REQUIRED",
        "target": "email",
        "message": "Email is required"
      },
      {
        "code": "INVALID_FORMAT",
        "target": "email",
        "message": "Invalid email format"
      },
      {
        "code": "MIN_LENGTH",
        "target": "password",
        "message": "Password must be at least 8 characters",
        "constraints": {
          "min": 8
        }
      }
    ]
  }
}

Business Rule Validation

{
  "error": {
    "code": "BUSINESS_RULE_VIOLATION",
    "message": "Cannot delete active user",
    "details": [
      {
        "code": "USER_ACTIVE",
        "target": "user",
        "message": "Cannot delete user with active subscriptions"
      }
    ]
  }
}

Authentication and Authorization

Authentication Error

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired authentication token",
    "details": [
      {
        "code": "TOKEN_EXPIRED",
        "target": "authorization",
        "message": "Token expired at 2025-06-30T12:00:00Z"
      }
    ]
  }
}

Authorization Error

{
  "error": {
    "code": "FORBIDDEN",
    "message": "Insufficient permissions",
    "details": [
      {
        "code": "MISSING_PERMISSION",
        "target": "user:delete",
        "message": "Requires 'admin' role"
      }
    ]
  }
}

Rate Limiting

Rate Limit Response Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1625040000
Retry-After: 60

Rate Limit Error

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests, please try again later",
    "details": [
      {
        "code": "RATE_LIMIT_REACHED",
        "target": "api",
        "message": "Rate limit of 100 requests per hour exceeded"
      }
    ],
    "retryAfter": 60
  }
}

Error Logging

Log Entry Example

{
  "timestamp": "2025-06-30T06:27:45.123Z",
  "level": "ERROR",
  "requestId": "a1b2c3d4",
  "correlationId": "x-correlation-id-value",
  "method": "POST",
  "path": "/api/users",
  "status": 400,
  "durationMs": 42,
  "userAgent": "Mozilla/5.0",
  "clientIp": "192.168.1.1",
  "error": {
    "name": "ValidationError",
    "message": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": [
      {
        "code": "REQUIRED",
        "target": "email",
        "message": "Email is required"
      }
    ],
    "stack": "ValidationError: Validation failed..."
  },
  "environment": "production",
  "version": "1.0.0"
}

Client-Side Handling

Error Handling Best Practices

  1. User-Friendly Messages: Map error codes to user-friendly messages
  2. Retry Logic: Implement retry for transient errors (5xx, 429)
  3. Circuit Breaker: Prevent cascading failures
  4. Error Boundaries: Gracefully handle UI errors
  5. Error Reporting: Report client-side errors to monitoring

Example Error Boundary (React)

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }

  componentDidCatch(error, errorInfo) {
    // Log error to error reporting service
    logErrorToService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return (
        <div className="error-boundary">
          <h2>Something went wrong</h2>
          <p>{this.state.error?.message}</p>
          <button onClick={() => window.location.reload()}>
            Reload Page
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}

Client Error Handling (JavaScript)

```javascript async function fetchWithErrorHandling(url, options = {}) { try { const response = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', ...options.headers, }, });

const data = await response.json();

if (!response.ok) {
  // Handle API errors
  const error = new Error(data.error?.message || 'API request failed');
  error.code = data.error?.code || 'API_ERROR';
  error.status = response.status;
  error.details = data.error?.details || [];
  throw error;
}

return data;

} catch (error) { if (error.name === 'AbortError') { console.log('Request was aborted'); throw new Error('Request was cancelled'); }

// Handle network errors
if (!navigator.onLine) {
  throw new Error('No internet connection');
}

// Re-throw the error for the caller to handle
throw error;

} }