finally — runs on every way out of the block, and a return inside it wins¶
Level: 201 · for anyone who writes cleanup code
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The questions below are what the finished page has to answer.
One line: finally runs however the try block is left — by return, throw, break or falling off the end — and a return inside it replaces the result and silently discards a thrown error; only ending the process, as process.exit() does, skips it.
Keywords: finally
What the finished page will answer¶
- What does
function f() { try { return "try" } finally { return "finally" } }return, and what happens to an error thrown in thetrywhenfinallyreturns? - If
tryreturnsxandfinallythen changesx, which value does the caller get? - Does
finallyrun onbreakandcontinueinside a loop, and before or after the loop's next turn? - Which exits skip
finally:process.exit(), an uncaught error in a timer callback, a generator that is never resumed? - In an
asyncfunction, doesfinallyrun after an awaited promise rejects, and before or after the caller'scatch?
Examples it will need¶
-
finally_return_wins_js.js— the result ofreturnintryagainstreturninfinally, a swallowed throw, and a variable changed afterreturn -
finally_in_loops_and_async_js.js— log lines showingfinallyonbreak, oncontinueand after an awaited rejection, in order -
finally_skipped_sh.sh— what prints whentrycallsprocess.exit(), and when a generator paused intryis never resumed
See also¶
throwandtry...catch— thetryandcatchthatfinallyfollows- Generators — a paused generator's
finallyruns only onreturn() usingandSymbol.dispose—using: cleanup without writingfinallyprocess—process.exit(), which skips everyfinally- Rust:
Drop, and what RAII buys ↗ — cleanup by scope instead, with Rust'sDrop - Concurrency: Who unlocks when the function returns early? ↗ — releasing a lock on every exit path, across languages