Skip to content
UniCircle
MediumConceptualError handling

try, catch, finally and error propagation

Question JS-ERR-001

How does try...catch...finally work? What does "error propagation" mean, and how do errors behave inside async code?

Show the explanation

Model answer.

  • try runs code that might throw.
  • catch (err) runs only if something in try threw; err is usually an Error with message and stack.
  • finally runs 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.

JavaScript
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.