Skip to main content

Error Handling

The PolarGrid SDKs provide typed errors for robust error handling.

Error Types

ErrorStatusDescription
AuthenticationError401Invalid or expired API key
ValidationError400Invalid request parameters
NotFoundError404Resource not found
RateLimitError429Rate limit exceeded
ServerError5xxServer-side error
NetworkErrorConnection failed
TimeoutErrorRequest timed out

Basic Error Handling

import {
  PolarGrid,
  isPolarGridError,
  AuthenticationError,
  ValidationError,
  RateLimitError,
  NetworkError,
  TimeoutError,
} from '@polargrid/sdk';

try {
  const response = await client.chatCompletion({
    model: 'llama-3.1-8b',
    messages: [{ role: 'user', content: 'Hello' }],
  });
} catch (error) {
  if (isPolarGridError(error)) {
    console.error(`Error: ${error.message}`);
    console.error(`Request ID: ${error.requestId}`);
    
    if (error instanceof AuthenticationError) {
      // Redirect to login or refresh API key
      console.error('Please check your API key');
    } else if (error instanceof ValidationError) {
      // Fix request parameters
      console.error('Invalid parameters:', error.details);
    } else if (error instanceof RateLimitError) {
      // Wait and retry
      console.error(`Retry after ${error.retryAfter} seconds`);
    } else if (error instanceof NetworkError) {
      // Check connection
      console.error('Network error - check your connection');
    } else if (error instanceof TimeoutError) {
      // Increase timeout or retry
      console.error('Request timed out');
    }
  } else {
    // Unknown error
    throw error;
  }
}

Retry Logic

The SDKs include automatic retry with exponential backoff for transient errors. Configure with:
const client = new PolarGrid({
  apiKey: 'pg_...',
  maxRetries: 3,  // Default: 3
  timeout: 30000, // Default: 30s
});

Custom Retry

For more control:
async function withRetry(fn, maxRetries = 3) {
  let lastError;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      
      // Don't retry auth errors
      if (error instanceof AuthenticationError) {
        throw error;
      }
      
      // Don't retry validation errors
      if (error instanceof ValidationError) {
        throw error;
      }
      
      // Exponential backoff
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(r => setTimeout(r, delay));
    }
  }
  
  throw lastError;
}

// Usage
const response = await withRetry(() => 
  client.chatCompletion({
    model: 'llama-3.1-8b',
    messages: [{ role: 'user', content: 'Hello' }],
  })
);

Rate Limiting

When rate limited, the RateLimitError includes a retryAfter property:
try {
  const response = await client.chatCompletion(request);
} catch (error) {
  if (error instanceof RateLimitError) {
    const waitMs = (error.retryAfter || 60) * 1000;
    await new Promise(r => setTimeout(r, waitMs));
    // Retry request
  }
}

Request IDs

Every request includes a unique ID for debugging. Include it when contacting support:
try {
  const response = await client.chatCompletion(request);
} catch (error) {
  if (isPolarGridError(error)) {
    console.error(`Request ID for support: ${error.requestId}`);
  }
}

Validation Errors

Validation errors include details about what’s wrong:
try {
  await client.chatCompletion({
    model: 'llama-3.1-8b',
    messages: [],  // Empty messages array
  });
} catch (error) {
  if (error instanceof ValidationError) {
    // error.message: "Messages array is required and cannot be empty"
    // error.details: { field: 'messages', reason: 'empty' }
  }
}

Debug Mode

Enable debug logging to see request/response details:
const client = new PolarGrid({
  apiKey: 'pg_...',
  debug: true,
});

// Logs:
// [PolarGrid] Making request (attempt 1): url=..., method=POST
// [PolarGrid] Request successful: requestId=..., status=200