Skip to main content

Error Hierarchy

Both SDKs share the same error class hierarchy. All errors extend from KaleidoError:
KaleidoError (base)
├── APIError (HTTP 400-599)
│   └── RateLimitError (HTTP 429)
├── NetworkError (connectivity issues)
├── ValidationError (HTTP 400, 422)
├── TimeoutError (HTTP 408, 504)
├── WebSocketError (WebSocket issues)
├── NotFoundError (HTTP 404)
├── ConfigError (configuration issues)
├── SwapError (swap operation failures)
├── NodeNotConfiguredError (node not set up)
├── QuoteExpiredError (quote expired)
└── InsufficientBalanceError (not enough funds)

Base Error: KaleidoError

All SDK errors extend KaleidoError with these properties:
PropertyTypeDescription
codestringError code for programmatic handling
messagestringHuman-readable error message
statusCode / status_codenumber?HTTP status code (if applicable)
detailsstring?Additional error details
isRetryable() / is_retryable()booleanWhether the error is safe to retry
import { KaleidoError } from 'kaleidoswap-sdk';

try {
  await client.maker.listPairs();
} catch (error) {
  if (error instanceof KaleidoError) {
    console.log(`Code: ${error.code}`);
    console.log(`Message: ${error.message}`);
    console.log(`Status: ${error.statusCode}`);
    console.log(`Retryable: ${error.isRetryable()}`);
  }
}

Specific Error Classes

APIError

Raised for HTTP errors (status 400-599).
import { APIError } from 'kaleidoswap-sdk';
// Properties: code='API_ERROR', statusCode, message, details

RateLimitError

Raised when rate limit is exceeded (HTTP 429). Extends APIError.
import { RateLimitError } from 'kaleidoswap-sdk';
// Additional property: retryAfter?: number (seconds)

try { /* ... */ } catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Retry after: ${error.retryAfter} seconds`);
  }
}

NetworkError

Raised for network connectivity issues (DNS failures, connection refused, etc.). Always retryable (isRetryable() returns true).

ValidationError

Raised for validation failures (HTTP 400, 422). Includes FastAPI validation error parsing.

TimeoutError

Raised when requests time out (HTTP 408, 504). Always retryable.

WebSocketError

Raised for WebSocket connection or communication errors.

NotFoundError

Raised when a resource is not found (HTTP 404).

ConfigError

Raised for SDK configuration issues (e.g., invalid URLs).

SwapError

Raised for swap operation failures.
import { SwapError } from 'kaleidoswap-sdk';
// Additional property: swapId?: string

try { /* ... */ } catch (error) {
  if (error instanceof SwapError) {
    console.log(`Swap failed: ${error.swapId}`);
  }
}

NodeNotConfiguredError

Raised when an RLN node operation is attempted without a configured nodeUrl.
import { NodeNotConfiguredError } from 'kaleidoswap-sdk';

try {
  await client.rln.getNodeInfo();
} catch (error) {
  if (error instanceof NodeNotConfiguredError) {
    console.log('Configure nodeUrl to use RLN operations');
  }
}

QuoteExpiredError

Raised when attempting to use an expired quote.

InsufficientBalanceError

Raised when a balance is insufficient for the requested operation.
import { InsufficientBalanceError } from 'kaleidoswap-sdk';
// Properties: requiredAmount: bigint, availableAmount: bigint, asset?: string

try { /* ... */ } catch (error) {
  if (error instanceof InsufficientBalanceError) {
    console.log(`Need: ${error.requiredAmount}, Have: ${error.availableAmount}`);
  }
}

Comprehensive Error Handling

import {
  KaleidoError,
  APIError,
  NetworkError,
  ValidationError,
  TimeoutError,
  NotFoundError,
  QuoteExpiredError,
  NodeNotConfiguredError,
  InsufficientBalanceError,
  RateLimitError,
} from 'kaleidoswap-sdk';

try {
  const quote = await client.maker.getQuote({ /* ... */ });
  const order = await client.maker.createSwapOrder({ /* ... */ });
} catch (error) {
  if (error instanceof QuoteExpiredError) {
    // Get a fresh quote and retry
  } else if (error instanceof InsufficientBalanceError) {
    console.log(`Need ${error.requiredAmount}, have ${error.availableAmount}`);
  } else if (error instanceof ValidationError) {
    console.log(`Invalid request: ${error.message}`);
  } else if (error instanceof RateLimitError) {
    // Wait and retry
    await new Promise(r => setTimeout(r, (error.retryAfter ?? 5) * 1000));
  } else if (error instanceof NotFoundError) {
    console.log('Resource not found');
  } else if (error instanceof TimeoutError) {
    console.log('Request timed out, retrying...');
  } else if (error instanceof NetworkError) {
    console.log('Network issue, check connectivity');
  } else if (error instanceof NodeNotConfiguredError) {
    console.log('Node not configured');
  } else if (error instanceof APIError) {
    console.log(`API error (${error.statusCode}): ${error.message}`);
  } else if (error instanceof KaleidoError) {
    console.log(`SDK error [${error.code}]: ${error.message}`);
  }
}

Retry Patterns

Use isRetryable() to implement automatic retries:
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error instanceof KaleidoError && error.isRetryable() && attempt < maxRetries - 1) {
        const delay = Math.pow(2, attempt) * 1000;
        await new Promise(r => setTimeout(r, delay));
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

const pairs = await withRetry(() => client.maker.listPairs());

HTTP Error Mapping

The SDK automatically maps HTTP errors to typed exceptions using mapHttpError / map_http_error:
HTTP StatusError Class
400, 422ValidationError
404NotFoundError
408, 504TimeoutError
429RateLimitError
500, 502, 503APIError
Other 4xxAPIError
Network failureNetworkError