Error Handling

Understanding and handling API errors

Error Response Format

All API errors follow a consistent JSON format:

json
{
  "error": "Error message describing what went wrong"
}

The HTTP status code indicates the error category, and the error message provides specific details.

HTTP Status Codes

Success Codes

200OK

Request successful, data returned

Client Error Codes

400Bad Request

The request was malformed or contains invalid parameters

Common causes:

  • Missing required query parameters
  • Invalid ticker_id format
  • Malformed request body
404Not Found

The requested resource does not exist

Common causes:

  • Invalid endpoint path
  • Ticker not found
  • DAO does not exist
429Too Many Requests

Rate limit exceeded

Details:

  • Limit: 60 requests per minute per IP
  • Reset: Wait until the next minute window

Server Error Codes

500Internal Server Error

An unexpected error occurred on the server

Common causes:

  • RPC connection issues
  • Blockchain data unavailable
  • Service temporarily down
502Bad Gateway

Upstream service (RPC) is unavailable

503Service Unavailable

API is temporarily unavailable (maintenance or overload)

Common Error Scenarios

Rate Limit Exceeded

When you exceed 60 requests per minute:

json
{
  "error": "Rate limit exceeded. Please try again later."
}

Solution:

  1. Implement Retry Logic

    Wait 60 seconds before retrying

  2. Use Exponential Backoff

    Gradually increase wait time between retries

  3. Cache Responses

    Store frequently accessed data locally

Example Implementation:

JavaScript
async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url);

      if (response.status === 429) {
        const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
        console.log(`Rate limited. Waiting ${waitTime}ms...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      }

      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

// Usage
const tickers = await fetchWithRetry('https://your-api-domain.com/api/tickers');
Python
import time
import requests
from typing import Optional, Dict

def fetch_with_retry(url: str, max_retries: int = 3) -> Optional[Dict]:
    for i in range(max_retries):
        try:
            response = requests.get(url)

            if response.status_code == 429:
                wait_time = (2 ** i) * 1  # Exponential backoff
                print(f"Rate limited. Waiting {wait_time}s...")
                time.sleep(wait_time)
                continue

            response.raise_for_status()
            return response.json()

        except requests.exceptions.RequestException as e:
            if i == max_retries - 1:
                raise e
            time.sleep(i + 1)

    return None

# Usage
tickers = fetch_with_retry('https://your-api-domain.com/api/tickers')

Ticker Not Found

When requesting a specific ticker that doesn't exist:

json
{
  "error": "Ticker not found: INVALID_MINT_ADDRESS"
}

Solutions:

  • Verify the ticker_id format: {BASE_MINT}_{QUOTE_MINT}
  • Ensure both mint addresses are valid Solana PublicKeys
  • Check if the DAO is excluded via EXCLUDED_DAOS
  • Verify the DAO has active pools with reserves

RPC Connection Issues

When the Solana RPC is unavailable:

json
{
  "error": "Failed to fetch DAO data from blockchain"
}

Solutions:

Check RPC Status

Verify your RPC provider is operational

Use Fallback RPC

Configure multiple RPC endpoints

Upgrade RPC Tier

Use a premium RPC provider

Retry Request

Implement automatic retry logic

Invalid Configuration

When required environment variables are missing:

json
{
  "error": "FACTORY_ADDRESS not configured"
}

Solution: Ensure all required environment variables are set in your .env file:

env
FACTORY_ADDRESS=YOUR_FACTORY_PROGRAM_ID
ROUTER_ADDRESS=YOUR_ROUTER_PROGRAM_ID

Error Handling Best Practices

Always Handle Errors

Never assume requests will succeed. Wrap all API calls in try-catch blocks.

javascript
try {
  const data = await fetch('/api/tickers').then(r => r.json());
} catch (error) {
  console.error('API request failed:', error);
  // Handle error appropriately
}
Implement Timeouts

Set reasonable timeouts to prevent hanging requests.

javascript
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 10000); // 10s timeout

try {
  const response = await fetch('/api/tickers', {
    signal: controller.signal
  });
  clearTimeout(timeout);
} catch (error) {
  if (error.name === 'AbortError') {
    console.error('Request timed out');
  }
}
Use Retry Logic

Implement exponential backoff for transient errors.

See code examples above for implementation details.

Cache Responses

Cache successful responses to reduce API load and improve resilience.

javascript
const cache = new Map();
const CACHE_TTL = 10000; // 10 seconds

async function getCached(url) {
  const cached = cache.get(url);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const data = await fetch(url).then(r => r.json());
  cache.set(url, { data, timestamp: Date.now() });
  return data;
}
Log Errors

Log all errors for debugging and monitoring.

javascript
async function fetchAPI(url) {
  try {
    return await fetch(url).then(r => r.json());
  } catch (error) {
    console.error({
      timestamp: new Date().toISOString(),
      url,
      error: error.message,
      stack: error.stack
    });
    throw error;
  }
}

Monitoring API Health

Use the health check endpoint to monitor API status:

bash
curl https://your-api-domain.com/health

Healthy Response:

json
{
  "status": "healthy",
  "timestamp": "2024-01-01T00:00:00.000Z",
  "uptime": 3600.5
}

Set up automated health checks every 1-5 minutes to detect issues early.

Getting Support

If you encounter persistent errors:

Error Response Examples

400 Bad Request
{
  "error": "Invalid ticker_id format. Expected: BASE_MINT_QUOTE_MINT"
}
404 Not Found
{
  "error": "Endpoint not found: /api/invalid"
}
429 Rate Limited
{
  "error": "Rate limit exceeded. Please try again later."
}
500 Server Error
{
  "error": "Failed to fetch DAO data from blockchain"
}
503 Service Unavailable
{
  "error": "Service temporarily unavailable. Please try again in a few moments."
}

Was this page helpful?