avoid_missing_completer_stack_trace
This rule flags a Completer.completeError(e) call inside a catch block that binds a stack trace but does not pass it on. The trace is available right there, and dropping it makes the resulting error much harder to diagnose.
Why use this rule
Section titled “Why use this rule”completeError takes an optional second argument, the stack trace. When it is omitted, the error still propagates, but the trace attached to it starts where the future was completed rather than where the failure actually occurred.
In practice that means the exception surfaces at the await with a stack that points into async plumbing, and the line that actually threw is gone. The information was in scope — catch (e, st) bound it — and simply not forwarded.
By default the rule only reports inside a catch clause that binds a stack-trace variable. That is the case where the fix is unambiguous: something to pass exists and is being discarded.
See also: dart:async Completer.completeError
try { await doWork();} catch (e, st) { completer.completeError(e); // `st` is discarded}try { await doWork();} catch (e, st) { completer.completeError(e, st);}Known limitations
Section titled “Known limitations”A bare catch (e) with no stack-trace parameter is not reported: nothing is in scope to pass, so the report would be unactionable. Widen with require_inside_catch: false if you want every call site flagged.
A completeError inside a closure declared within the catch block is not reported either. The closure runs on its own schedule and cannot be assumed to still have meaningful access to the enclosing trace.
Matching is by static type, so any subtype of Completer is covered, and a same-named completeError on an unrelated class is not.
Turning this rule off
Section titled “Turning this rule off”This rule is in the recommended preset, so it is on with
preset: recommended or preset: opinionated. Add it to preset: core with
avoid_missing_completer_stack_trace: true.
To turn it off:
rules: avoid_missing_completer_stack_trace: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_missing_completer_stack_trace: require_inside_catch: falserules: avoid_missing_completer_stack_trace: require_inside_catch: false| Option | Type | Default | Description |
|---|---|---|---|
require_inside_catch |
bool | true |
Only report inside a catch clause that binds a stack trace. Set to false to flag every completeError call with a single argument |
Related rules
Section titled “Related rules”avoid_catch_error— Use try/catch instead of Future.catchError.avoid_future_ignore— Do not silently suppress Future errors with an unexplained ignore call.avoid_nested_futures— Don’t declare Future<Future<T>>.avoid_passing_async_when_sync_expected— Don’t pass an async closure where a void-returning function is expected.