or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

error-handling.mdexchange-management.mdindex.mdmarket-data.mdprecision.mdtrading.mdutilities.mdwebsocket.md
tile.json

error-handling.mddocs/

Error Handling

Error handling provides a comprehensive classification system for proper error handling and debugging in cryptocurrency trading applications. CCXT uses a hierarchical error system that allows developers to catch and handle specific error types appropriately.

Capabilities

Base Error Classes

Foundation error classes that all CCXT errors extend from.

/**
 * Base error classes
 */
class BaseError extends Error {
  constructor(message: string);
}

class ExchangeError extends BaseError {
  constructor(message: string);
}

class NetworkError extends BaseError {
  constructor(message: string);
}

Usage Examples:

import ccxt, { BaseError, ExchangeError, NetworkError } from 'ccxt';

try {
  const exchange = new ccxt.binance();
  const ticker = await exchange.fetchTicker('BTC/USDT');
} catch (error) {
  if (error instanceof NetworkError) {
    console.log('Network issue - retry may help');
  } else if (error instanceof ExchangeError) {
    console.log('Exchange-specific error');
  } else if (error instanceof BaseError) {
    console.log('CCXT error');
  } else {
    console.log('Unexpected error');
  }
}

Authentication Errors

Errors related to API authentication and authorization.

/**
 * Authentication error classes
 */
class AuthenticationError extends ExchangeError {
  constructor(message: string);
}

class PermissionDenied extends AuthenticationError {
  constructor(message: string);
}

class AccountNotEnabled extends PermissionDenied {
  constructor(message: string);
}

class AccountSuspended extends AuthenticationError {
  constructor(message: string);
}

Usage Examples:

import ccxt, { AuthenticationError, PermissionDenied, AccountSuspended } from 'ccxt';

async function handleAuthenticatedRequest(exchange) {
  try {
    return await exchange.fetchBalance();
  } catch (error) {
    if (error instanceof AccountSuspended) {
      console.error('Account is suspended - contact exchange support');
      throw error; // Re-throw as this needs manual intervention
    } else if (error instanceof AccountNotEnabled) {
      console.error('Account not enabled for trading');
      // Redirect user to enable trading
    } else if (error instanceof PermissionDenied) {
      console.error('API key lacks required permissions');
      // Request user to check API key permissions
    } else if (error instanceof AuthenticationError) {
      console.error('Authentication failed - check API credentials');
      // Prompt user to re-enter credentials
    }
    throw error;
  }
}

Request Errors

Errors related to malformed or invalid requests.

/**
 * Request error classes
 */
class ArgumentsRequired extends ExchangeError {
  constructor(message: string);
}

class BadRequest extends ExchangeError {
  constructor(message: string);
}

class BadSymbol extends BadRequest {
  constructor(message: string);
}

class InvalidNonce extends BadRequest {
  constructor(message: string);
}

Usage Examples:

import ccxt, { ArgumentsRequired, BadSymbol, InvalidNonce } from 'ccxt';

async function safeCreateOrder(exchange, symbol, type, side, amount, price) {
  try {
    return await exchange.createOrder(symbol, type, side, amount, price);
  } catch (error) {
    if (error instanceof BadSymbol) {
      console.error(`Invalid trading pair: ${symbol}`);
      // Show user available symbols
      const markets = await exchange.loadMarkets();
      const availableSymbols = Object.keys(markets);
      console.log('Available symbols:', availableSymbols.slice(0, 10));
    } else if (error instanceof ArgumentsRequired) {
      console.error('Missing required parameters for order creation');
      // Validate all required parameters are provided
    } else if (error instanceof InvalidNonce) {
      console.error('Invalid nonce - check system time synchronization');
      // Sync system time or adjust nonce generation
    }
    throw error;
  }
}

Trading Errors

Errors specific to trading operations and order management.

/**
 * Trading error classes
 */
class InsufficientFunds extends ExchangeError {
  constructor(message: string);
}

class InvalidOrder extends ExchangeError {
  constructor(message: string);
}

class OrderNotFound extends ExchangeError {
  constructor(message: string);
}

class OrderNotCached extends ExchangeError {
  constructor(message: string);
}

class OrderImmediatelyFillable extends ExchangeError {
  constructor(message: string);
}

class OrderNotFillable extends ExchangeError {
  constructor(message: string);
}

class DuplicateOrderId extends ExchangeError {
  constructor(message: string);
}

class CancelPending extends ExchangeError {
  constructor(message: string);
}

Usage Examples:

import ccxt, { 
  InsufficientFunds, 
  InvalidOrder, 
  OrderNotFound, 
  OrderImmediatelyFillable 
} from 'ccxt';

async function handleTradingErrors(exchange, symbol, type, side, amount, price) {
  try {
    const order = await exchange.createOrder(symbol, type, side, amount, price);
    return order;
  } catch (error) {
    if (error instanceof InsufficientFunds) {
      console.error('Insufficient balance for order');
      const balance = await exchange.fetchBalance();
      console.log('Current balance:', balance);
      // Show user their available balance
    } else if (error instanceof InvalidOrder) {
      console.error('Invalid order parameters');
      // Validate order parameters against market limits
      const market = exchange.market(symbol);
      console.log('Market limits:', market.limits);
    } else if (error instanceof OrderImmediatelyFillable) {
      console.warn('Order would execute immediately - consider market order');
      // Suggest using market order instead
    } else if (error instanceof OrderNotFound) {
      console.error('Order not found when trying to cancel/modify');
      // Refresh order status
    }
    throw error;
  }
}

Network Errors

Errors related to network connectivity and communication issues.

/**
 * Network error classes
 */
class NetworkError extends BaseError {
  constructor(message: string);
}

class DDoSProtection extends NetworkError {
  constructor(message: string);
}

class RateLimitExceeded extends NetworkError {
  constructor(message: string);
}

class ExchangeNotAvailable extends NetworkError {
  constructor(message: string);
}

class OnMaintenance extends ExchangeNotAvailable {
  constructor(message: string);
}

class RequestTimeout extends NetworkError {
  constructor(message: string);
}

class BadResponse extends NetworkError {
  constructor(message: string);
}

class NullResponse extends BadResponse {
  constructor(message: string);
}

Usage Examples:

import ccxt, { 
  RateLimitExceeded, 
  RequestTimeout, 
  OnMaintenance, 
  DDoSProtection 
} from 'ccxt';

async function robustApiCall(exchange, apiMethod, ...args) {
  const maxRetries = 3;
  let retryCount = 0;
  
  while (retryCount < maxRetries) {
    try {
      return await exchange[apiMethod](...args);
    } catch (error) {
      retryCount++;
      
      if (error instanceof RateLimitExceeded) {
        console.log(`Rate limit exceeded - waiting ${exchange.rateLimit}ms`);
        await new Promise(resolve => setTimeout(resolve, exchange.rateLimit));
      } else if (error instanceof RequestTimeout) {
        console.log(`Request timeout - retry ${retryCount}/${maxRetries}`);
        await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
      } else if (error instanceof OnMaintenance) {
        console.log('Exchange is under maintenance');
        throw error; // Don't retry maintenance errors
      } else if (error instanceof DDoSProtection) {
        console.log('DDoS protection active - waiting longer');
        await new Promise(resolve => setTimeout(resolve, 5000 * retryCount));
      } else {
        throw error; // Don't retry other errors
      }
      
      if (retryCount >= maxRetries) {
        console.error(`Failed after ${maxRetries} retries`);
        throw error;
      }
    }
  }
}

System Errors

Errors related to exchange system status and operational issues.

/**
 * System error classes
 */
class OperationRejected extends ExchangeError {
  constructor(message: string);
}

class NoChange extends OperationRejected {
  constructor(message: string);
}

class MarginModeAlreadySet extends NoChange {
  constructor(message: string);
}

class MarketClosed extends OperationRejected {
  constructor(message: string);
}

class ManualInteractionNeeded extends OperationRejected {
  constructor(message: string);
}

class RestrictedLocation extends OperationRejected {
  constructor(message: string);
}

class ContractUnavailable extends OperationRejected {
  constructor(message: string);
}

Usage Examples:

import ccxt, { 
  MarketClosed, 
  RestrictedLocation, 
  ManualInteractionNeeded,
  MarginModeAlreadySet 
} from 'ccxt';

async function handleSystemErrors(exchange, operation) {
  try {
    return await operation();
  } catch (error) {
    if (error instanceof MarketClosed) {
      console.error('Market is closed for trading');
      const status = await exchange.fetchStatus();
      console.log('Exchange status:', status);
      // Wait for market to reopen
    } else if (error instanceof RestrictedLocation) {
      console.error('Trading restricted in your location');
      // Show user location restrictions
    } else if (error instanceof ManualInteractionNeeded) {
      console.error('Manual intervention required');
      // Direct user to exchange website
    } else if (error instanceof MarginModeAlreadySet) {
      console.warn('Margin mode already set to requested value');
      // Continue operation as desired state is already achieved
    }
    throw error;
  }
}

Configuration Errors

Errors related to exchange configuration and settings.

/**
 * Configuration error classes
 */
class NotSupported extends ExchangeError {
  constructor(message: string);
}

class InvalidProxySettings extends ExchangeError {
  constructor(message: string);
}

class ExchangeClosedByUser extends ExchangeError {
  constructor(message: string);
}

class ChecksumError extends ExchangeError {
  constructor(message: string);
}

Usage Examples:

import ccxt, { NotSupported, InvalidProxySettings } from 'ccxt';

function checkExchangeSupport(exchange, feature) {
  if (!exchange.has[feature]) {
    throw new NotSupported(`${exchange.name} does not support ${feature}`);
  }
}

async function configuredExchange(exchangeClass, config) {
  try {
    const exchange = new exchangeClass(config);
    
    // Check required features
    checkExchangeSupport(exchange, 'fetchTicker');
    checkExchangeSupport(exchange, 'createOrder');
    
    return exchange;
  } catch (error) {
    if (error instanceof NotSupported) {
      console.error(`Feature not supported: ${error.message}`);
      // Fallback to supported features or different exchange
    } else if (error instanceof InvalidProxySettings) {
      console.error('Invalid proxy configuration');
      // Prompt user to correct proxy settings
    }
    throw error;
  }
}

Error Handling Patterns

Common patterns for comprehensive error handling in trading applications.

/**
 * Error handling utility patterns
 */
interface ErrorHandler {
  handleError(error: Error, context?: any): Promise<any>;
  isRetryable(error: Error): boolean;
  getRetryDelay(error: Error, attempt: number): number;
}

Usage Examples:

import ccxt from 'ccxt';

class TradingErrorHandler {
  constructor(exchange) {
    this.exchange = exchange;
  }
  
  async withErrorHandling(operation, context = {}) {
    const maxRetries = 3;
    let attempt = 0;
    
    while (attempt < maxRetries) {
      try {
        return await operation();
      } catch (error) {
        attempt++;
        
        if (!this.isRetryable(error) || attempt >= maxRetries) {
          await this.logError(error, context, attempt);
          throw error;
        }
        
        const delay = this.getRetryDelay(error, attempt);
        console.log(`Retrying in ${delay}ms (attempt ${attempt}/${maxRetries})`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }
  
  isRetryable(error) {
    return error instanceof ccxt.NetworkError ||
           error instanceof ccxt.RequestTimeout ||
           error instanceof ccxt.RateLimitExceeded;
  }
  
  getRetryDelay(error, attempt) {
    if (error instanceof ccxt.RateLimitExceeded) {
      return this.exchange.rateLimit * attempt;
    }
    return 1000 * Math.pow(2, attempt); // Exponential backoff
  }
  
  async logError(error, context, attempt) {
    const errorInfo = {
      type: error.constructor.name,
      message: error.message,
      context,
      attempt,
      timestamp: new Date().toISOString(),
    };
    
    console.error('Trading error:', errorInfo);
    
    // Could send to monitoring service
    // await this.sendToMonitoring(errorInfo);
  }
}

// Usage
const exchange = new ccxt.binance({ /* config */ });
const errorHandler = new TradingErrorHandler(exchange);

async function robustTradingOperation() {
  return await errorHandler.withErrorHandling(async () => {
    const balance = await exchange.fetchBalance();
    return await exchange.createOrder('BTC/USDT', 'limit', 'buy', 0.001, 50000);
  }, { operation: 'createOrder', symbol: 'BTC/USDT' });
}