Async Error Handling

Handle errors in async operations

JavaScriptIntermediate
JavaScript
// Method 1: Async/await with try-catch
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Fetch error:', error.message);
        throw error;
    }
}

fetchData().catch(error => {
    console.error('Unhandled:', error);
});

// Method 2: Promise error handling
function promiseOperation() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.5) {
                reject(new Error('Random failure'));
            } else {
                resolve('Success');
            }
        }, 1000);
    });
}

promiseOperation()
    .then(result => console.log('Result:', result))
    .catch(error => console.error('Error:', error.message));

// Method 3: Multiple async operations
async function fetchMultiple() {
    try {
        const [data1, data2, data3] = await Promise.all([
            fetch('https://api.example.com/data1').then(r => r.json()),
            fetch('https://api.example.com/data2').then(r => r.json()),
            fetch('https://api.example.com/data3').then(r => r.json())
        ]);
        return [data1, data2, data3];
    } catch (error) {
        console.error('One or more requests failed:', error);
        throw error;
    }
}

// Method 4: Promise.allSettled
async function fetchAllSettled() {
    const results = await Promise.allSettled([
        fetch('https://api.example.com/data1'),
        fetch('https://api.example.com/data2'),
        fetch('https://api.example.com/data3')
    ]);
    
    results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
            console.log(`Request ${index + 1} succeeded`);
        } else {
            console.error(`Request ${index + 1} failed:`, result.reason);
        }
    });
}

// Method 5: Unhandled promise rejection
process.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled rejection:', reason);
});

// Method 6: Async error wrapper
function asyncHandler(fn) {
    return (req, res, next) => {
        Promise.resolve(fn(req, res, next)).catch(next);
    };
}

// Usage in Express
const asyncRoute = asyncHandler(async (req, res) => {
    const data = await fetchData();
    res.json(data);
});

Output

Fetch error: Failed to fetch
Error: Random failure
One or more requests failed: Error
Request 1 succeeded
Request 2 failed: Error
Request 3 succeeded

Async error handling requires special care.

Async/Await

  • Use try-catch
  • Handle in async functions
  • Re-throw if needed

Promises

  • .catch() handler
  • Chain error handling
  • Handle rejections

Promise.all

  • Fails fast
  • First error stops all
  • Use try-catch

Promise.allSettled

  • All complete
  • Check status
  • Handle individually

Unhandled Rejections

  • Global handler
  • Log errors
  • Prevent crashes

Best Practices

  • Always handle errors
  • Use asyncHandler wrapper
  • Log properly
  • Don't ignore rejections