Error Retry Logic

Implement retry logic for failed operations

JavaScriptIntermediate
JavaScript
// Method 1: Simple retry
async function retryOperation(fn, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await fn();
        } catch (error) {
            if (i === maxRetries - 1) throw error;
            console.log(`Retry ${i + 1} failed, retrying...`);
            await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
        }
    }
}

// Method 2: Retry with exponential backoff
async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await fn();
        } catch (error) {
            if (i === maxRetries - 1) throw error;
            const delay = baseDelay * Math.pow(2, i);
            console.log(`Retry ${i + 1} after ${delay}ms`);
            await new Promise(resolve => setTimeout(resolve, delay));
        }
    }
}

// Method 3: Retry with conditions
async function retryWithCondition(fn, shouldRetry, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await fn();
        } catch (error) {
            if (!shouldRetry(error) || i === maxRetries - 1) {
                throw error;
            }
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
    }
}

// Usage
retryWithCondition(
    () => fetch('https://api.example.com/data'),
    (error) => error.message.includes('network') || error.message.includes('timeout'),
    3
);

// Method 4: Retry class
class RetryHandler {
    constructor(options = {}) {
        this.maxRetries = options.maxRetries || 3;
        this.delay = options.delay || 1000;
        this.backoff = options.backoff || 'exponential';
    }
    
    async execute(fn) {
        for (let i = 0; i < this.maxRetries; i++) {
            try {
                return await fn();
            } catch (error) {
                if (i === this.maxRetries - 1) throw error;
                
                const delay = this.calculateDelay(i);
                await this.wait(delay);
            }
        }
    }
    
    calculateDelay(attempt) {
        if (this.backoff === 'exponential') {
            return this.delay * Math.pow(2, attempt);
        }
        return this.delay;
    }
    
    wait(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

const retryHandler = new RetryHandler({ maxRetries: 3, delay: 1000 });
retryHandler.execute(() => fetch('https://api.example.com/data'));

Output

Retry 1 failed, retrying...
Retry 2 failed, retrying...
Retry 1 after 1000ms
Retry 2 after 2000ms

Retry logic handles transient failures.

Simple Retry

  • Fixed attempts
  • Fixed delay
  • Re-throw on failure

Exponential Backoff

  • Increasing delays
  • 1s, 2s, 4s, etc.
  • Reduces load

Conditional Retry

  • Check error type
  • Retry only certain errors
  • Skip others

Retry Class

  • Configurable
  • Reusable
  • Flexible

Use Cases

  • Network requests
  • Database operations
  • External APIs
  • Transient failures

Best Practices

  • Limit retries
  • Use backoff
  • Check error types
  • Don't retry forever