finallyStatementSafety
Reports control flow statements in
finallyblocks that can override control flow intry/catchblocks.
✅ This rule is included in the ts logical preset.
Control flow statements such as return, throw, break, and continue in finally blocks can cause unexpected behavior.
When these statements appear in a finally block, they override any control flow statements in the corresponding try or catch blocks.
The finally block always executes, and its control flow statements take precedence, which can lead to bugs that are difficult to diagnose.
Examples
Section titled “Examples”function processData() { try { return fetchData(); } finally { return null; }}function handleError() { try { throw new Error("Original error"); } catch (error) { throw error; } finally { throw new Error("Override error"); }}for (let i = 0; i < items.length; i++) { try { processItem(items[i]); } finally { break; }}function processData() { try { return fetchData(); } finally { cleanup(); }}function handleError() { try { throw new Error("Original error"); } catch (error) { console.error(error); throw error; } finally { cleanup(); }}for (let i = 0; i < items.length; i++) { try { processItem(items[i]); break; } finally { cleanup(); }}Options
Section titled “Options”This rule is not configurable.
When Not To Use It
Section titled “When Not To Use It”If you are very confident in your handling of exception handling in your code and specifically want to use the confusing quirks of finally control flow statements, this rule might not be for you.
Further Reading
Section titled “Further Reading”Equivalents in Other Linters
Section titled “Equivalents in Other Linters”- Biome:
noUnsafeFinally - Deno:
no-unsafe-finally - ESLint:
no-unsafe-finally - Oxlint:
eslint/no-unsafe-finally
Made with ❤️🔥 in Boston by
Josh Goldberg and contributors.