A try statement evaluates its block to a completion: normal, return, throw, break, or continue. The catch and finally clauses then run according to that completion.
catchruns only for a throw. Its parameter is bound to the thrown value, and thecatchblock's own completion becomes the result. Ifcatchthrows, the new error replaces the old one.finallyruns for every completion. That includesreturn,break,continue, and a throw that nocatchhandled.- A normal
finallyis transparent. The originalreturnorthrowis resumed afterwards. Areturnoperand is evaluated beforefinallyruns, so changesfinallymakes to that variable do not change the returned value. - An abrupt
finallywins. Areturn,throw,break, orcontinueinsidefinallydiscards the pending outcome. Areturninfinallytherefore silently swallows an error fromtry. Linters flag this (no-unsafe-finally), so avoid it. - Optional catch binding.
catch { ... }is allowed when you do not need the error. - You can throw any value.
throw 'oops'orthrow { code: 1 }is legal, andcatchreceives it as is. Such values have nostack, andinstanceof Errorisfalse. ThrowErrorobjects so callers get a stack and amessage.
Use finally for cleanup that must run on every path, such as releasing a lock or hiding a spinner. Do not put control flow in it.