乐闻世界logo
搜索文章和话题

How to handle Promise errors?

2月22日 14:07

Promise error handling is an essential skill when working with Promises. Proper error handling ensures program robustness and prevents uncaught errors from causing program crashes.

Basic Methods of Error Handling

1. Using .catch() Method

.catch() is the primary method for Promise error handling, catching errors thrown anywhere in the chain:

javascript
Promise.resolve() .then(() => { throw new Error('Error occurred'); }) .catch(error => { console.error('Caught error:', error.message); });

2. Handling in the Second Parameter of .then()

The .then() method can accept two parameters: success callback and failure callback:

javascript
Promise.resolve() .then( result => console.log('Success:', result), error => console.error('Failure:', error.message) );

Note: This error handling only catches errors from the previous Promise and won't catch errors later in the chain.

Error Propagation Mechanism

Errors Propagate Down the Promise Chain

javascript
Promise.resolve() .then(() => { throw new Error('First error'); }) .then(() => { console.log('This line will not execute'); }) .then(() => { console.log('This line will also not execute'); }) .catch(error => { console.error('Finally caught:', error.message); // Output: Finally caught: First error });

Errors Can Be Recovered After Being Caught

javascript
Promise.resolve() .then(() => { throw new Error('Error occurred'); }) .catch(error => { console.error('Caught error:', error.message); return 'Recovered value'; // Return a value, chain can continue }) .then(value => { console.log('Continue execution:', value); // Output: Continue execution: Recovered value });

Common Error Handling Scenarios

1. Network Request Error Handling

javascript
fetch('/api/data') .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { console.log('Data:', data); }) .catch(error => { console.error('Request failed:', error.message); // Can show error message to user here showErrorToUser('Data loading failed, please try again later'); });

2. Error Handling for Multiple Promises

javascript
Promise.all([promise1, promise2, promise3]) .then(results => { console.log('All successful:', results); }) .catch(error => { console.error('At least one failed:', error.message); });

3. Handling Partial Failures with Promise.allSettled

javascript
Promise.allSettled([promise1, promise2, promise3]) .then(results => { results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Promise ${index} succeeded:`, result.value); } else { console.error(`Promise ${index} failed:`, result.reason); } }); });

Error Handling Best Practices

1. Always Add Error Handling

javascript
// Not recommended: no error handling fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)); // Recommended: add error handling fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));

2. Use finally for Cleanup

javascript
let isLoading = true; fetch('/api/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)) .finally(() => { isLoading = false; console.log('Request completed, whether successful or failed'); });

3. Make Error Handling Specific

javascript
// Not recommended: generic error handling Promise.resolve() .catch(error => { console.error('Error occurred'); }); // Recommended: specific error handling Promise.resolve() .catch(error => { if (error instanceof NetworkError) { console.error('Network error:', error.message); } else if (error instanceof ValidationError) { console.error('Validation error:', error.message); } else { console.error('Unknown error:', error.message); } });

4. Consider Error Recovery Strategies

javascript
async function fetchDataWithRetry(url, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error(`Attempt ${i + 1} failed:`, error.message); if (i === maxRetries - 1) { throw error; // Last attempt failed, throw error } // Wait before retrying await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } } }

Error Handling in async/await

Using try/catch

javascript
async function fetchData() { try { const response = await fetch('/api/data'); const data = await response.json(); console.log('Data:', data); } catch (error) { console.error('Error:', error.message); // Error handling logic } }

Catching Specific Errors

javascript
async function fetchData() { try { const response = await fetch('/api/data'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { if (error.name === 'TypeError') { console.error('Network connection problem'); } else if (error.message.includes('HTTP error')) { console.error('Server error'); } else { console.error('Unknown error:', error); } throw error; // Can choose to rethrow error } }

Uncaught Promise Errors

Global Error Handling

javascript
// Handle uncaught Promise errors window.addEventListener('unhandledrejection', event => { console.error('Uncaught Promise error:', event.reason); // Can log error or show error message here event.preventDefault(); // Prevent default error output }); // In Node.js environment process.on('unhandledRejection', (reason, promise) => { console.error('Uncaught Promise error:', reason); });

Common Error Handling Pitfalls

1. Forgetting to Add catch in Chain

javascript
// Dangerous: no error handling Promise.reject('Error occurred') .then(result => console.log(result)); // Error will bubble to global, potentially causing program crash // Safe: add error handling Promise.reject('Error occurred') .then(result => console.log(result)) .catch(error => console.error(error));

2. Forgetting to Rethrow Errors in catch

javascript
// Potentially problematic: error is swallowed Promise.reject('Error occurred') .catch(error => { console.error('Caught error:', error); // Forgot to rethrow, subsequent code will continue executing }) .then(() => { console.log('This will execute even though there was an error earlier'); }); // Recommended: decide whether to rethrow based on situation Promise.reject('Error occurred') .catch(error => { console.error('Caught error:', error); // If error cannot be recovered, rethrow throw error; });

3. Mixing then's Second Parameter with catch

javascript
// Not recommended: confusing Promise.resolve() .then( result => console.log('Success'), error => console.error('Failure1') ) .catch(error => console.error('Failure2')); // Recommended: use catch uniformly Promise.resolve() .then(result => console.log('Success')) .catch(error => console.error('Failure'));

Summary

  1. Always add error handling: Use .catch() or try/catch
  2. Understand error propagation: Errors propagate down the Promise chain
  3. Use finally for cleanup: Put code that must execute regardless of success or failure in finally
  4. Make error handling specific: Handle different error types differently
  5. Consider error recovery: Implement retry mechanisms or fallback strategies
  6. Avoid swallowing errors: Ensure errors are properly handled or rethrown
  7. Global error monitoring: Use global error handlers to catch unhandled errors
标签:Promise