Skip to content
Last updated

Error Handling

Understand and handle API errors effectively.

Error Response Format

When an error occurs, the API returns a structured error response:

{
  "detail": "Error message describing what went wrong",
  "error_code": "SPECIFIC_ERROR_CODE",
  "field_errors": {
    "field_name": ["Field-specific error message"]
  }
}

HTTP Status Codes

Client Errors (4xx)

CodeErrorMeaning
400Bad RequestInvalid request format or parameters
401UnauthorizedMissing or invalid authentication
403ForbiddenValid auth but insufficient permissions
404Not FoundResource doesn't exist
409ConflictRequest conflicts with current state
422Unprocessable EntityValidation error
429Too Many RequestsRate limit exceeded

Server Errors (5xx)

CodeErrorMeaning
500Internal Server ErrorSomething went wrong on our end
502Bad GatewayTemporary service issue
503Service UnavailableService temporarily unavailable
504Gateway TimeoutRequest took too long

Common Errors

400 Bad Request

Cause: Malformed JSON or invalid parameters

{
  "detail": "JSON parse error - Expecting value"
}

Solution: Validate your JSON syntax and request parameters.


401 Unauthorized

Cause: Missing or invalid API token

{
  "detail": "Authentication credentials were not provided."
}

Solution: Check that you're including the Authorization header with a valid token.


403 Forbidden

Cause: Insufficient permissions

{
  "detail": "You do not have permission to perform this action."
}

Solution: Verify your user role has the required permissions for this operation.


404 Not Found

Cause: Resource doesn't exist

{
  "detail": "Not found."
}

Solution: Verify the resource ID and ensure it exists.


422 Validation Error

Cause: Invalid field values

{
  "identifier": ["This field is required."],
  "assessment_type": ["Invalid choice."]
}

Solution: Review the field errors and fix the invalid values.


429 Rate Limit Exceeded

Cause: Too many requests

{
  "detail": "Request was throttled. Expected available in 3600 seconds."
}

Solution: Implement exponential backoff and respect rate limits.

Error Handling Patterns

JavaScript/TypeScript

async function makeApiCall(url: string) {
  try {
    const response = await fetch(url, {
      headers: {
        'Authorization': `Bearer ${API_TOKEN}`,
        'Content-Type': 'application/json'
      }
    });

    if (!response.ok) {
      const error = await response.json();
      
      switch (response.status) {
        case 400:
          throw new ValidationError(error.detail);
        case 401:
          throw new AuthenticationError('Invalid token');
        case 403:
          throw new PermissionError('Insufficient permissions');
        case 404:
          throw new NotFoundError('Resource not found');
        case 429:
          throw new RateLimitError('Rate limit exceeded');
        default:
          throw new APIError(error.detail);
      }
    }

    return await response.json();
  } catch (error) {
    console.error('API Error:', error);
    throw error;
  }
}

Python

import requests
from requests.exceptions import HTTPError

class APIError(Exception):
    pass

class AuthenticationError(APIError):
    pass

class ValidationError(APIError):
    pass

def make_api_call(url):
    try:
        response = requests.get(
            url,
            headers={
                'Authorization': f'Bearer {API_TOKEN}',
                'Content-Type': 'application/json'
            }
        )
        response.raise_for_status()
        return response.json()
        
    except HTTPError as e:
        status_code = e.response.status_code
        error_data = e.response.json()
        
        if status_code == 401:
            raise AuthenticationError('Invalid token')
        elif status_code == 422:
            raise ValidationError(error_data)
        elif status_code == 429:
            # Implement retry logic
            time.sleep(60)
            return make_api_call(url)
        else:
            raise APIError(error_data.get('detail'))

Retry Logic

Exponential Backoff

For transient errors (429, 5xx), implement exponential backoff:

import time
from typing import Optional

def make_request_with_retry(
    url: str,
    max_retries: int = 3,
    backoff_factor: int = 2
) -> Optional[dict]:
    
    for attempt in range(max_retries):
        try:
            response = requests.get(url, headers=headers)
            response.raise_for_status()
            return response.json()
            
        except requests.exceptions.HTTPError as e:
            status_code = e.response.status_code
            
            # Don't retry client errors (except rate limit)
            if 400 <= status_code < 500 and status_code != 429:
                raise
            
            # Calculate wait time
            wait_time = backoff_factor ** attempt
            
            if attempt < max_retries - 1:
                print(f"Retry {attempt + 1}/{max_retries} after {wait_time}s")
                time.sleep(wait_time)
            else:
                raise

Validation Errors

Handle field-level validation errors:

interface ValidationErrorResponse {
  [field: string]: string[];
}

function handleValidationError(errors: ValidationErrorResponse) {
  const formattedErrors = Object.entries(errors).map(
    ([field, messages]) => ({
      field,
      message: messages.join(', ')
    })
  );
  
  // Display errors to user
  formattedErrors.forEach(({ field, message }) => {
    showFieldError(field, message);
  });
}

Logging & Monitoring

What to Log

Do log:

  • Error messages and codes
  • Request IDs (if provided)
  • Timestamp
  • Endpoint and method
  • Status code

Don't log:

  • API tokens
  • Sensitive user data
  • Personal information

Example

function logApiError(error, context) {
  console.error({
    timestamp: new Date().toISOString(),
    endpoint: context.url,
    method: context.method,
    status: error.status,
    message: error.message,
    // Don't log: token, user data
  });
}

Best Practices

  1. Always check status codes before processing responses
  2. Implement retry logic for 429 and 5xx errors
  3. Validate data client-side before sending to reduce 422 errors
  4. Display user-friendly messages instead of raw API errors
  5. Monitor error rates to detect issues early
  6. Cache tokens to avoid authentication errors
  7. Handle network failures gracefully

Need Help?

If you encounter persistent errors:

  1. Check API Status
  2. Review the API Reference
  3. Contact support@coolset.com

Include these details when reporting errors:

  • Timestamp
  • Endpoint and method
  • Status code and error message
  • Request ID (if available)

Next Steps