throw-in-finally

Same as throw_in_finally in Dart lints

Path
lint/correctness/throw-in-finally
Default
On (recommended)
Origin
Dart lints
Rule
441 of 512
recommended

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

example.dartdart
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();
  }
}
Avoid using `throw` in a `finally` block.
8 } finally {
9 throw Ex();
Avoid using `throw` in a `finally` block.
18 } finally {
19 throw Ex();
Avoid using `throw` in a `finally` block.
27 if (c) {
28 throw StateError('bad');
Avoid using `throw` in a `finally` block.
36 } finally {
37 final v = value ?? (throw ArgumentError());
Avoid using `throw` in a `finally` block.
46 for (final value in values) {
47 if (value < 0) throw RangeError(value);
Avoid using `throw` in a `finally` block.
58 } finally {
59 throw Ex();
Avoid using `throw` in a `finally` block.
71 } finally {
72 throw Ex();

Valid

example.dartdart
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.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "throw-in-finally": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/throw-in-finally: <reason>
  • type-literal-in-constant-patterntype_literal_in_constant_patternrecommended

    Don't use constant patterns whose expressions have the core Type type.

  • undeclared-dependenciescross-file

    Report package imports and exports missing from the enclosing pubspec.

  • unnecessary-flutter-importsrecommendedflutter

    Disallow unused Flutter framework and dart:async imports.

  • unnecessary-nullablecheck-unnecessary-nullablecross-file

    Flags private function or method parameters whose nullable type is unnecessary.

  • unnecessary-nullable-return-typeunnecessary_nullable_return_type

    Disallow nullable return types on functions that never return null.

  • unnecessary-statementsunnecessary_statementsrecommended

    Flags expression statements whose expression has no clear effect.

  • unrelated-type-equality-checksunrelated_type_equality_checksrecommended

    Reports ==/!= comparisons and relational ==/!= patterns whose operand types are unrelated.

  • unused-codecheck-unused-codecross-file

    Report public top-level declarations that nothing references.