Docs
README
18.2 Advanced Error Handling
Overview
Proper error handling in asynchronous code is crucial for building robust applications. This section covers advanced patterns for handling errors in async operations.
Error Propagation in Async Code
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Async Error Propagation ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā // Promises - errors propagate through chain ā
ā fetchUser() ā
ā .then(processUser) // Error here... ā
ā .then(saveUser) // ...skips this... ā
ā .then(notifyUser) // ...and this... ā
ā .catch(handleError); // ...caught here! ā
ā ā
ā // Async/await - use try/catch ā
ā async function doWork() { ā
ā try { ā
ā const user = await fetchUser(); ā
ā const processed = await processUser(user); ā
ā await saveUser(processed); ā
ā } catch (error) { ā
ā // Any error from above caught here ā
ā } ā
ā } ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Error Types in Async Code
| Error Type | Description | Example |
|---|---|---|
| Network Error | Failed requests | Fetch failed |
| Timeout Error | Operation too slow | Request timeout |
| Validation Error | Invalid data | Bad JSON |
| Auth Error | Permission denied | 401 Unauthorized |
| Rate Limit Error | Too many requests | 429 Too Many Requests |
Error Handling Patterns
1. Try-Catch with Async/Await
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
throw error; // Re-throw or handle
}
}
2. Catch at Multiple Levels
async function process() {
try {
const data = await fetchData();
try {
await saveData(data);
} catch (saveError) {
// Handle save-specific errors
await handleSaveFailure(data);
}
} catch (fetchError) {
// Handle fetch errors
}
}
3. Error Recovery
async function fetchWithFallback() {
try {
return await fetchPrimary();
} catch {
console.log('Primary failed, trying fallback...');
return await fetchFallback();
}
}
Global Error Handlers
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Global Error Handlers ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā // Unhandled Promise Rejections (Node.js/Browser) ā
ā window.addEventListener('unhandledrejection', event => { ā
ā console.error('Unhandled rejection:', event.reason); ā
ā event.preventDefault(); // Prevent default logging ā
ā }); ā
ā ā
ā // Node.js specific ā
ā process.on('unhandledRejection', (reason, promise) => { ā
ā console.error('Unhandled Rejection at:', promise); ā
ā }); ā
ā ā
ā // General errors ā
ā window.onerror = function(msg, url, line, col, error) { ā
ā console.error('Error:', msg); ā
ā return true; // Prevent default ā
ā }; ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Custom Error Classes
class NetworkError extends Error {
constructor(message, statusCode) {
super(message);
this.name = 'NetworkError';
this.statusCode = statusCode;
}
}
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
Summary
- ā¢Always handle async errors
- ā¢Use try/catch with async/await
- ā¢Create custom error types
- ā¢Set up global handlers as safety net
- ā¢Log errors for debugging
- ā¢Provide meaningful error messages