How does try...catch...finally work? What does "error propagation" mean, and how do errors behave inside async code?
Show the explanation
Model answer.
tryruns code that might throw.catch (err)runs only if something intrythrew;erris usually anErrorwithmessageandstack.finallyruns always, whether the code succeeded, threw or returned: the place to release resources (close a file, hide a spinner).
Propagation: if a function does not catch an error, it travels up the call stack to the caller, then its caller, until something catches it. If nothing does, it becomes an uncaught error.
function parsePrice(text) {
const n = Number(text);
if (Number.isNaN(n)) throw new RangeError(`Not a price: ${text}`);
return n;
}
try { parsePrice('abc'); }
catch (err) { if (err instanceof RangeError) showMessage(err.message); else throw err; }
finally { stopLoading(); }Async: a try/catch around code that schedules a callback will not catch errors thrown later inside it. With promises, use .catch() or await inside try. Unhandled promise rejections are reported separately (and crash Node by default).
Good practice: throw Error objects (not strings), catch only what you can handle, and re-throw the rest.
Original UniCircle question. Last reviewed 22 Oct 2026.
