Hint
Catch what you can handle; re-throw everything else; never silently swallow errors
Error propagation means letting errors bubble up the call stack until something can meaningfully handle them.
// ❌ Anti-pattern: silently swallowing errors
try {
await doSomething();
} catch (err) {} // hides all bugs — never do this!
// ❌ Anti-pattern: catching all errors at every level
async function fetchUser(id) {
try { return await fetch(...); }
catch (err) {
console.log('error!'); // useless — caller doesn't know what happened
}
}
// ✅ Correct pattern: handle what you can, re-throw the rest
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new NetworkError('Not found', res.status);
return await res.json();
} catch (err) {
if (err instanceof NetworkError && err.statusCode === 404) {
return null; // 404 is expected — handle it
}
throw err; // unexpected error — propagate up
}
}
// ✅ Top-level handler
async function main() {
try {
const user = await fetchUser(1);
render(user);
} catch (err) {
logToErrorService(err); // catch everything remaining
showErrorMessage();
}
}