What If Something Breaks?
Async errors cannot be caught by a regular try..catch because they happen outside the current call stack. Promises have their own built-in error handling mechanism.
.catch() — The Error Handler
.catch(fn) is equivalent to .then(null, fn). It catches any error that occurred anywhere in the chain above it.
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => processData(data))
.catch(err => {
// Catches errors from ALL the .then() steps above!
console.error('Something failed:', err.message);
showUserFriendlyError();
})
.finally(() => {
hideLoadingSpinner(); // Always runs, success or failure
});
Re-throwing Errors
You can catch an error, handle it partially, and then re-throw it for a higher-level handler:
fetch('/data')
.catch(err => {
if (err.name === 'NetworkError') {
showOfflineMessage();
return []; // Recover gracefully — return a default value
}
throw err; // Unknown error? Re-throw it!
})
.catch(err => logToCrashReporter(err)); // Catches re-thrown errors
Warning
A promise chain without a .catch() will silently fail. The error appears in the console as " Uncaught (in promise) " and your code just stops. Always add a .catch() at the end of your chains!