Skip to main content
OnchainDB SDKs provide specific error types for comprehensive error handling.

Error Types

Error TypeDescription
OnchainDBErrorBase error class for all SDK errors
ValidationErrorData validation failed
TransactionErrorBlockchain transaction failed
PaymentRequiredErrorPayment required (HTTP 402)
PaymentVerificationErrorPayment verification failed

Basic Error Handling

import {
  OnchainDBError,
  TransactionError,
  ValidationError,
  PaymentRequiredError,
  PaymentVerificationError,
} from '@onchaindb/sdk';

try {
  await client.store(
    { collection: 'test', data: [{ test: 'data' }] },
    paymentCallback
  );
} catch (error) {
  if (error instanceof ValidationError) {
    console.log('Validation failed:', error.message);
    console.log('Details:', error.details);
  } else if (error instanceof TransactionError) {
    console.log('Transaction failed:', error.transactionId);
  } else if (error instanceof PaymentRequiredError) {
    console.log('Payment required');
    console.log('Amount:', error.quote.totalCostTia, 'TIA');
    console.log('Pay to:', error.quote.brokerAddress);
  } else if (error instanceof PaymentVerificationError) {
    console.log('Payment verification failed:', error.txHash);
  } else if (error instanceof OnchainDBError) {
    console.log('OnchainDB error:', error.code, error.statusCode);
  }
}

Validation Errors

Thrown when data validation fails:
try {
  await client.createDocument('users', {
    email: 'invalid-email',
    age: -5
  }, paymentProof);
} catch (error) {
  if (error instanceof ValidationError) {
    console.log('Validation errors:');
    Object.entries(error.details).forEach(([field, messages]) => {
      console.log(`  ${field}: ${messages.join(', ')}`);
    });
  }
}

Payment Required Handling

Handle x402 payment required errors:
try {
  const result = await client.queryBuilder()
    .collection('premium_data')
    .selectAll()
    .execute();
} catch (error) {
  if (error instanceof PaymentRequiredError) {
    const quote = error.quote;
    console.log('Payment required');
    console.log('Amount:', quote.totalCostTia, 'TIA');
    console.log('Pay to:', quote.brokerAddress);
    console.log('Expires:', new Date(quote.expiresAt * 1000));

    // Handle payment flow
    const txHash = await processPayment(quote);
    // Retry with payment proof
  }
}

Retry Pattern with Exponential Backoff

async function storeWithRetry(
  data: any,
  maxRetries: number = 3,
  delay: number = 1000
) {
  let lastError: Error;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await client.store(data, paymentCallback, true);
    } catch (error) {
      lastError = error;

      // Don't retry validation errors
      if (error instanceof ValidationError) {
        throw error;
      }

      // Don't retry payment required (needs user action)
      if (error instanceof PaymentRequiredError) {
        throw error;
      }

      // Retry transient errors
      if (error instanceof TransactionError || error instanceof OnchainDBError) {
        console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 2; // Exponential backoff
        continue;
      }

      throw error;
    }
  }

  throw lastError;
}

Error Logging

function logError(error: Error) {
  const timestamp = new Date().toISOString();

  if (error instanceof ValidationError) {
    console.error(`[${timestamp}] Validation Error:`, {
      message: error.message,
      details: error.details,
      code: error.code
    });
  } else if (error instanceof TransactionError) {
    console.error(`[${timestamp}] Transaction Error:`, {
      message: error.message,
      transactionId: error.transactionId,
      blockHeight: error.blockHeight
    });
  } else if (error instanceof PaymentRequiredError) {
    console.error(`[${timestamp}] Payment Required:`, {
      quoteId: error.quote.quoteId,
      amount: error.quote.totalCostTia
    });
  } else {
    console.error(`[${timestamp}] Error:`, error.message);
  }
}

Next Steps