passsy / dart-lint

An opinionated, community-driven set of lint rules for Dart and Flutter projects. Like pedantic but stricter
Apache License 2.0
277 stars 82 forks source link

Enable unawaited_futures, ship fireAndForget #33

Closed passsy closed 10 months ago

passsy commented 3 years ago

Enables unawaited_futures.

Where Futures are intentionally not awaited, users can disable this lint with fireAndForget which exists as top-level function and extension. It is identical to unawaited from pedantic.

Future<void> logAsync(String msg) async { /*...*/ }

Future<void> someOperation() async {
  await doSomething();

  // Warning: `Future` results in `async` function bodies must be `await`ed or marked `unawaited` using `package:pedantic`.
  logAsync('success');

  // The fireAndForget() extensions signals that await is intentionally missing
  logAsync('success').fireAndForget();

  // The fireAndForget() function signals that await is intentionally missing
  fireAndForget(logAsync('success'));
}

I explicitly did not name it unawaited as it causes naming conflicts. That's the main reason why unawaited was removed from meta again.

Fixes #26

Alternative names

passsy commented 3 years ago

I'm not 100% convinced fireAndForget is a good API. The wording should match the error message and should contain "unawaited".

Idea: Force a justification why await wasn't called

  logAsync('success').unawaitedBecause("logging isn't cirical for control flow");
  unawaitedBecause('user does not have to wait for logging', logAsync('success'));

I have to double-check if the string is removed when compiled AOT, since it isn't used.

passsy commented 3 years ago

Can't land this yet. There is currently a great discussion going on at https://github.com/dart-lang/sdk/issues/46218.

A common method that returns Future but is not awaited is AnimationController.forward(). Let's see how the dart team solves it

triallax commented 2 years ago

Just a heads-up: dart:async has had unawaited since Dart 2.15.

passsy commented 10 months ago

Let's stick with the official unawaited. I still like the idea of unawaitedBecause but it should come from an official Dart package