Skip to main content
JavaScript & the browser·Module C7 · Lesson 4
TaskWrite withSpinner(work) that logs 'spinner on', calls work() in try/catch/finally, logs 'caught: ' + err.message if it throws, and logs 'spinner off' in finally — re-throw the error after. Call it with work = () => { throw new Error('boom') } inside an outer try/catch; outer catch logs 'outer: ' + err.message.

try / catch / finally

100 XP7 min
Theory

finally runs always

finally runs whether or not the try threw — even if the catch threw, even if a return happened. It's the only safe place for cleanup that MUST happen.

function withConnection(work) {
  const conn = openConnection();
  try {
    return work(conn);
  } catch (err) {
    console.error("work failed:", err);
    throw err;
  } finally {
    conn.close();   // ALWAYS runs
  }
}

Common shape

The "wrap a risky thing, always tear it down" pattern:

  • Open a file → finally close it.
  • Start a transaction → finally rollback if not committed.
  • Show a spinner → finally hide it.

Re-throwing

throw err inside a catch re-throws the same error. The finally still runs first; then the throw propagates to the caller. The original stack is preserved.

return inside finally is a trap

return inside finally overrides any return from try/catch and silently swallows pending throws. Always use finally for SIDE EFFECTS, never for return values.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 10 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.