discarded-futures
Same as discarded_futures in Dart lints
- Group
- Correctness
- Path
lint/correctness/discarded-futures- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 220 of 512
Don't discard Futures returned by calls in synchronous functions.
A Future created inside a non-async function and then dropped can't be
awaited, so its errors and completion are lost:
void save() {
writeFile(); // BAD
}
Future<void> save() async {
await writeFile(); // GOOD
}
Expression statements, cascade sections, and string interpolations whose
resolved type is Future (or a subtype) or FutureOr are reported inside
synchronous bodies. Assignments, Future.delayed(duration, computation),
Map.putIfAbsent, and members annotated @awaitNotRequired, including
inherited, extension, and local functions, are exempt; local annotations
follow the visible declaration rather than a reusable name. Function typedef
annotations follow the invoked value's immediate alias through inferred
variables, fields, records, and collections, but not explicit .call or an
unannotated alias of that typedef. Member calls, including null-aware
accesses, use the reached receiver branch for annotation lookup, as do
bounded type parameters and flow-promoted FutureOr values. Unresolved
types stay silent. Calls through getters underline the complete callee expression,
while method invocations underline only the method name.
Invalid
import 'dart:async';
Future<int> fetch() async => 1;
FutureOr<int> maybeFetch() => 1;
class Api {
Future<void> save() async {}
Future<int> get pending async => 1;
}
void callsFunction() {
fetch();
}
void callsMethod(Api api) {
api.save();
}
void readsGetter(Api api) {
api.pending;
}
void callsFutureOr() {
maybeFetch();
}
void cascade(Api api) {
api..save();
}
void interpolates() {
print('${fetch()}');
}
void inClosure() {
final callback = () {
fetch();
};
callback();
}
class Widget {
void initState() {
fetch();
}
}void callsFunction() { fetch();void callsMethod(Api api) { api.save();void readsGetter(Api api) { api.pending;void callsFutureOr() { maybeFetch();void cascade(Api api) { api..save();void interpolates() { print('${fetch()}'); final callback = () { fetch(); void initState() { fetch();Valid
import 'dart:async';
import 'package:meta/meta.dart' show awaitNotRequired;
import 'package:meta/meta.dart' as meta;
Future<int> fetch() async => 1;
class Api {
Future<void> save() async {}
}
Future<void> asyncBody() async {
fetch();
await fetch();
}
void assigned() {
final future = fetch();
future.ignore();
}
Future<int> returned() {
return fetch();
}
void unawaitedCall() {
unawaited(fetch());
}
void delayed() {
Future.delayed(Duration.zero, () => 1);
}
void putIfAbsent(Map<String, Future<int>> cache) {
cache.putIfAbsent('key', fetch);
}
Future<int> arrow() => fetch();
void syncValue() {
print(1);
}
void assignment(Api api) {
Future<void> pending;
pending = api.save();
pending.ignore();
}
void annotatedLocalFunctions() {
@awaitNotRequired
Future<void> handleError() async {}
handleError();
print('${handleError()}');
@meta.awaitNotRequired
Future<void> prefixed() async {}
prefixed();
}Configure discarded-futures
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"discarded-futures": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/discarded-futures: <reason>More correctness rules
- dispose-fieldsrecommendedflutter
Requires other owned disposable State fields to be released in
dispose(). - dispose-focus-node-and-timerrecommendedflutter
Requires owned
FocusNodeand Timer fields to be released inState.dispose(). - dispose-provided-instancesrecommendedriverpod
Flags provider-created instances with a dispose method that lack ref.onDispose cleanup.
- dispose-provider-resourcesrecommendedriverpod
Flags provider-created resources without autoDispose or ref.onDispose cleanup.
- dispose-providersrecommendedprovider
Requires cleanup callbacks for disposable values created by package:provider's Provider.
- emit-new-bloc-state-instancesrecommendedbloc
Flags Bloc and Cubit emissions that reuse their current state instance.
- exhaustive-cases
exhaustive_casesrecommendedRequire switch statements over enum-like classes to cover every constant value.
- function-always-returns-null
Flags value functions with a proven explicit null return on every path.