dart-lang / linter

Linter for Dart.
https://dart.dev/tools/linter-rules
BSD 3-Clause "New" or "Revised" License
628 stars 170 forks source link

proposal: `no_raw_futures` #4008

Open Rexios80 opened 1 year ago

Rexios80 commented 1 year ago

no_raw_futures (maybe no_async_then?)

Description

Do not call Future.then(). Call await instead. Maybe only enforce in async methods?

Details

Future.then() is much less readable than await calls. To the point where I think Future.then() should be deprecated but that's outside of our scope.

Kind

Enforce style

Bad Examples

void bad() async {
  Future.delayed(const Duration(seconds: 1)).then((_) => print('bleh'));
}

Real code my coworkers came up with

Future<void> forceUpdate(Function onSuccess, Function onFailure) async {
  await InAppUpdate.checkForUpdate().then((value) async {
    final AppUpdateResult result =
        await InAppUpdate.performImmediateUpdate().catchError((dynamic e) {
      _logger.e('Perform update failed', e);
    });
    if (result == AppUpdateResult.success) {
      onSuccess.call();
    } else {
      onFailure.call();
    }
  }).catchError((dynamic e) {
    _logger.e('Check update failed', e);
  });
}

Good Examples

void good() async {
  await Future.delayed(const Duration(seconds: 1));
  print('better');
}

Coworkers code that I rewrote

Future<void> forceUpdate(
  VoidCallback onSuccess,
  VoidCallback onFailure,
) async {
  try {
    await InAppUpdate.checkForUpdate();
  } catch (e) {
    _logger.e('Check update failed', e);
    onFailure();
    return;
  }
  final AppUpdateResult result;
  try {
    result = await InAppUpdate.performImmediateUpdate();
  } catch (e) {
    _logger.e('Perform update failed', e);
    onFailure();
    return;
  }
  if (result == AppUpdateResult.success) {
    onSuccess();
  } else {
    onFailure();
  }
}

Discussion

My coworkers keep using Future.then() in async methods and I wish they would stop it.

Effective Dart: https://dart.dev/guides/language/effective-dart/usage#prefer-asyncawait-over-using-raw-futures Dart Code Metrics: https://dcm.dev/docs/individuals/rules/common/prefer-async-await/

I feel like there should already be a proposal for this, but I couldn't find one.

Discussion checklist

Rexios80 commented 1 year ago

Ah I finally found one: https://github.com/dart-lang/linter/issues/525

Feel free to close this issue if you feel it shouldn't exist

incendial commented 1 year ago

If you're interested in trying out _dart_codemetrics package, we have this rule available https://dcm.dev/docs/rules/common/prefer-async-await/

Rexios80 commented 2 weeks ago

I wrote a simple implementation of this rule in my linter package here: https://github.com/Rexios80/rexios_lints/blob/445f781ccb96ca92a812440a8cfba87b2348e532/lib/custom_lint/prefer_async_await.dart