How does try...catch work?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
try marks code that might throw. If something does, execution of the try block stops immediately and jumps to catch. finally runs afterwards either way.
try {
const data = JSON.parse(input); // may throw
use(data); // skipped if the line above threw
} catch (err) {
console.error(err.message);
} finally {
setLoading(false); // always runs
}
The binding is optional when you do not need the error: catch { ... }.
finally runs even on return
function f() {
try { return "a"; }
finally { console.log("cleanup"); } // logs before the value is returned
}
That makes it the right place to release resources. But avoid returning from finally — it silently discards the value or error from the try block, which hides bugs.
What it cannot catch
- Errors thrown later, in a callback: a
setTimeoutbody runs on a different tick, long after thetryhas exited. - Rejected promises, unless you
awaitthem inside the block. - Syntax errors — the file never parses, so no runtime construct can help.
Catch narrowly
Wrapping a whole function in try catches failures you did not anticipate and turns them into silence. Wrap the specific operation instead, and rethrow what you cannot handle:
catch (err) {
if (err instanceof ValidationError) return showMessage(err);
throw err; // not ours
}
An empty catch {} is the worst outcome — the program continues in a broken state with no trace of why.
Two details
The caught value is not guaranteed to be an Error; anything can be thrown, so err.message may be undefined. And a try block has its own scope, so const declared inside it is not visible afterwards — declare the variable outside if you need it later.
