Unsafe Control Flow Inside Finally
ID |
javascript.unsafe_finally |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
reliability, suspicious-comparison |
Description
Reports return, throw, break, and continue statements inside a finally block. Such statements override any pending exception or return value from the surrounding try / catch, silently swallowing errors and producing behaviour that depends on subtle execution-order details.
Rationale
finally runs after a possibly-thrown exception or a return value is committed but before it propagates. A return / throw / break / continue inside finally replaces the pending result, hiding the original outcome:
// Bad - the thrown error is swallowed; the function returns "swallowed"
function f() {
try {
throw new Error("oops");
} finally {
return "swallowed";
}
}
Statements that exit a function or loop declared inside the finally block are safe — they don’t escape the finally.
Remediation
Move the control flow out of finally, or restructure so that finally only contains side-effecting cleanup that doesn’t return / throw.
// Good
function f() {
try {
return doWork();
} finally {
cleanup();
}
}