return, break or continue inside a finally block

ID

dart.correctness.control_flow_in_finally

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Control Flow

Language

Dart

Description

Reports return, break and continue statements written directly in a finally block, rather than inside a loop, switch or closure that the finally block itself contains.

Rationale

A finally block runs while an exception is still propagating. Transferring control out of it abandons that propagation: the exception is discarded, the caller sees a normal completion, and the value the try block was about to return is replaced. The failure then disappears without a trace, which is the hardest class of bug to diagnose because the code looks like it succeeded. A return in the finally block also silently overrides a return in the try block, so the two read as if both took effect when only one does.

The following code illustrates the pattern detected by this rule:

class Uploader {
  bool sendAll(List<String> items) {
    for (final item in items) {
      // FLAGGED: return, break or continue inside a finally block
      try {
        send(item);
      } finally {
        close();
        continue;
      }
    }
    return true;
  }

  bool transmit(String item) => true;
  void close() {}
  void log(String m) {}
  bool closed = false;
}

Remediation

Keep the finally block to cleanup that cannot fail — closing handles, releasing locks, restoring state — and let control flow stay in the try or catch block. If a value really has to be replaced or a loop cut short, do it after the try statement, or move the decision into a catch clause where the exception is handled explicitly.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved