Error Recovery

Recover from errors gracefully

JavaScriptAdvanced
JavaScript
// Method 1: Fallback values
function fetchWithFallback(url, fallback) {
    return fetch(url)
        .then(response => response.json())
        .catch(error => {
            console.warn('Fetch failed, using fallback:', error);
            return fallback;
        });
}

// Method 2: Retry with fallback
async function operationWithFallback(primary, fallback, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await primary();
        } catch (error) {
            if (i === maxRetries - 1) {
                console.warn('Primary failed, using fallback');
                return await fallback();
            }
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
    }
}

// Method 3: Circuit breaker
class CircuitBreaker {
    constructor(threshold = 5, timeout = 60000) {
        this.failures = 0;
        this.threshold = threshold;
        this.timeout = timeout;
        this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
        this.nextAttempt = Date.now();
    }
    
    async execute(fn) {
        if (this.state === 'OPEN') {
            if (Date.now() < this.nextAttempt) {
                throw new Error('Circuit breaker is OPEN');
            }
            this.state = 'HALF_OPEN';
        }
        
        try {
            const result = await fn();
            this.onSuccess();
            return result;
        } catch (error) {
            this.onFailure();
            throw error;
        }
    }
    
    onSuccess() {
        this.failures = 0;
        this.state = 'CLOSED';
    }
    
    onFailure() {
        this.failures++;
        if (this.failures >= this.threshold) {
            this.state = 'OPEN';
            this.nextAttempt = Date.now() + this.timeout;
        }
    }
}

const breaker = new CircuitBreaker();
breaker.execute(() => fetch('https://api.example.com/data'));

// Method 4: Graceful degradation
function featureWithFallback(feature, fallback) {
    try {
        return feature();
    } catch (error) {
        console.warn('Feature unavailable, using fallback');
        return fallback();
    }
}

// Method 5: Error recovery strategies
class RecoveryStrategy {
    static async retry(fn, maxRetries) {
        // Retry logic
    }
    
    static async fallback(fn, fallbackFn) {
        try {
            return await fn();
        } catch (error) {
            return await fallbackFn();
        }
    }
    
    static async timeout(fn, timeoutMs, fallback) {
        return Promise.race([
            fn(),
            new Promise((_, reject) => 
                setTimeout(() => reject(new Error('Timeout')), timeoutMs)
            )
        ]).catch(() => fallback());
    }
}

Output

Fetch failed, using fallback: Error
Primary failed, using fallback

Error recovery maintains functionality.

Fallback Values

  • Default data
  • Cached data
  • Static content
  • Graceful degradation

Retry with Fallback

  • Try primary
  • Retry if fails
  • Use fallback
  • Maintain service

Circuit Breaker

  • Prevent cascading failures
  • Open on threshold
  • Half-open for testing
  • Close on success

Graceful Degradation

  • Feature unavailable
  • Use simpler version
  • Maintain core functionality
  • User experience

Recovery Strategies

  • Retry
  • Fallback
  • Timeout
  • Multiple strategies

Best Practices

  • Plan for failures
  • Have fallbacks
  • Monitor recovery
  • Test strategies