Skip to main content

Usage Examples

Basic Error Handling

import { Connection, Transaction, Keypair } from '@solana/web3.js';
import { extractProgramError } from './errors';

async function executeTradeWithErrorHandling(
connection: Connection,
transaction: Transaction,
signers: Keypair[]
) {
try {
const signature = await connection.sendTransaction(transaction, signers);
await connection.confirmTransaction(signature);

console.log('Trade executed successfully:', signature);
return signature;

} catch (error) {
const perpetualError = extractProgramError(error);

if (perpetualError) {
console.error('Trading Error:', {
code: perpetualError.code,
name: perpetualError.name,
message: perpetualError.message,
category: perpetualError.category
});

switch (perpetualError.code) {
case 2: // InsufficientFunds
throw new Error('Please deposit more collateral before trading');

case 120: // InsufficientLiquidity
throw new Error('Pool lacks liquidity - try smaller trade size');

case 162: // LiquidationThresholdExceeded
throw new Error('Position would be liquidated - add margin first');

case 361: // TradingPaused
throw new Error('Trading is currently paused by admin');

default:
throw new Error(`Trading failed: ${perpetualError.message}`);
}
}

throw error;
}
}

Error Recovery Strategies

/**
* Retry with exponential backoff for transient errors
*/
async function executeWithRetry(
fn: () => Promise<any>,
maxRetries: number = 3
): Promise<any> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
const perpetualError = extractProgramError(error);

const nonRetryableErrors = [
2, // InsufficientFunds
40, // OrderNotFound
162, // LiquidationThresholdExceeded
361, // TradingPaused
];

if (perpetualError && nonRetryableErrors.includes(perpetualError.code)) {
throw error;
}

if (i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}

throw error;
}
}

throw new Error('Retry attempts exhausted');
}

User-Friendly Error Messages

/**
* Convert technical error to user-friendly message
*/
function getUserFriendlyErrorMessage(error: any): string {
const perpetualError = extractProgramError(error);

if (!perpetualError) {
return 'An unexpected error occurred. Please try again.';
}

const userMessages: Record<number, string> = {
2: 'You don\'t have enough funds. Please deposit more collateral.',
20: 'You don\'t have permission to perform this action.',
21: 'This operation requires an authorized keeper.',
40: 'The order you\'re looking for doesn\'t exist.',
45: 'Your order size is too small. Minimum order size is required.',
46: 'Your order size is too large. Please reduce it.',
80: 'This limit order has expired. Please create a new one.',
100: 'Invalid price provided.',
101: 'Price data is too old. Please wait for oracle update.',
120: 'There isn\'t enough liquidity in the pool for this trade.',
162: 'This action would put your position at risk of liquidation.',
167: 'The leverage you requested is too high.',
207: 'Your deposit is too small. Please deposit more.',
313: 'No position found. Please open a position first.',
361: 'Trading is currently paused. Please try again later.',
};

return userMessages[perpetualError.code] || perpetualError.message;
}

Logging and Monitoring

/**
* Log error for monitoring
*/
function logError(error: any, context: string) {
const perpetualError = extractProgramError(error);

if (perpetualError) {
console.error('Program Error:', {
context,
code: perpetualError.code,
name: perpetualError.name,
message: perpetualError.message,
category: perpetualError.category,
timestamp: new Date().toISOString()
});

// Example: send to monitoring service
// analytics.track('program_error', { ... });
} else {
console.error('Unknown Error:', {
context,
error: error.toString(),
timestamp: new Date().toISOString()
});
}
}