throw-in-finally
Same as throw_in_finally in Dart lints
- Group
- Correctness
- Path
lint/correctness/throw-in-finally- Default
- On (recommended)
- Origin
- Dart lints
- Rule
- 441 of 512
Flags throw inside a finally block.
Throwing from a finally replaces whatever the try or catch was doing: an
exception that was still propagating is silently discarded and a value the
try was about to return is lost. Keep finally blocks limited to cleanup. A
throw inside a closure or local function defined in the finally is left
alone, as is a throw whose innermost enclosing try is nested inside the
finally (in its body or catch clauses).
try {
work();
} finally {
throw StateError('cleanup failed'); // flagged
}
Invalid
class Ex implements Exception {}
void doThing() {}
void direct() {
try {
doThing();
} finally {
throw Ex();
}
}
void afterCatch() {
try {
doThing();
} catch (e) {
print(e);
} finally {
throw Ex();
}
}
void conditional(bool c) {
try {
doThing();
} finally {
if (c) {
throw StateError('bad');
}
}
}
void asExpression(int? value) {
try {
doThing();
} finally {
final v = value ?? (throw ArgumentError());
print(v);
}
}
void inLoop(List<int> values) {
try {
doThing();
} finally {
for (final value in values) {
if (value < 0) throw RangeError(value);
}
}
}
void nestedFinally() {
try {
doThing();
} finally {
try {
doThing();
} finally {
throw Ex();
}
}
}
void closureWithOwnTry() {
try {
doThing();
} finally {
void cleanup() {
try {
doThing();
} finally {
throw Ex();
}
}
cleanup();
}
} } finally { throw Ex(); } finally { throw Ex(); if (c) { throw StateError('bad'); } finally { final v = value ?? (throw ArgumentError()); for (final value in values) { if (value < 0) throw RangeError(value); } finally { throw Ex(); } finally { throw Ex();Valid
class Ex implements Exception {}
void doThing() {}
void inTry() {
try {
throw Ex();
} finally {
print('cleanup');
}
}
void inCatch() {
try {
doThing();
} catch (e) {
throw Ex();
} finally {
print('cleanup');
}
}
void rethrowInCatch() {
try {
doThing();
} catch (e) {
rethrow;
} finally {
print('cleanup');
}
}
// A closure defined in the finally does not throw from it.
void closure() {
try {
doThing();
} finally {
final fail = () => throw Ex();
void local() {
throw Ex();
}
print([fail, local]);
}
}
// The innermost enclosing try owns the throw.
void nestedTryBody() {
try {
doThing();
} finally {
try {
throw Ex();
} catch (e) {
print(e);
}
}
}
void nestedTryCatch() {
try {
doThing();
} finally {
try {
doThing();
} catch (e) {
throw Ex();
}
}
}
void outside() {
try {
doThing();
} finally {
print('cleanup');
}
throw Ex();
}Configure throw-in-finally
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"throw-in-finally": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/throw-in-finally: <reason>More correctness rules
- type-literal-in-constant-pattern
type_literal_in_constant_patternrecommendedDon't use constant patterns whose expressions have the core
Typetype. - undeclared-dependenciescross-file
Report package imports and exports missing from the enclosing pubspec.
- unnecessary-flutter-importsrecommendedflutter
Disallow unused Flutter framework and
dart:asyncimports. - unnecessary-nullable
check-unnecessary-nullablecross-fileFlags private function or method parameters whose nullable type is unnecessary.
- unnecessary-nullable-return-type
unnecessary_nullable_return_typeDisallow nullable return types on functions that never return null.
- unnecessary-statements
unnecessary_statementsrecommendedFlags expression statements whose expression has no clear effect.
- unrelated-type-equality-checks
unrelated_type_equality_checksrecommendedReports
==/!=comparisons and relational==/!=patterns whose operand types are unrelated. - unused-code
check-unused-codecross-fileReport public top-level declarations that nothing references.