avoid-passing-async-when-sync-expected

Same as avoid-passing-async-when-sync-expected in Dart Code Metrics

Path
lint/suspicious/avoid-passing-async-when-sync-expected
Default
On (recommended)
Origin
Dart Code Metrics
Rule
108 of 512
recommended

Flags an async closure passed to a proven synchronous callback parameter.

Invalid

example.dartdart
// Bad: passing async function to sync parameter
void processSync(void Function() callback) {
  callback();
}

void example() {
  processSync(() async {
    await Future.delayed(Duration(seconds: 1));
    print('Done');
  });
}

class Handler {
  void setup(void Function(String) handler) {
    handler('test');
  }

  void badSetup() {
    setup((value) async {
      await processAsync(value);
    });
  }
}

void executeCallback(String Function(int) fn) {
  print(fn(42));
}

void misuse() {
  executeCallback((n) async {
    await delay();
    return '$n';
  });
}

// More violations
void performAction(void Function(String, int) callback) {
  callback('test', 42);
}

void badAction() {
  performAction((name, count) async {
    await Future.delayed(Duration(milliseconds: 100));
    print('$name: $count');
  });
}

class DataLoader {
  void loadData(String Function() fetcher) {
    final data = fetcher();
    print(data);
  }

  void loadBad() {
    loadData(() async {
      await Future.delayed(Duration(seconds: 1));
      return 'data';
    });
  }
}

void namedCallback({required void Function() callback}) {}

void badNamed() {
  namedCallback(callback: () async {});
}
Avoid passing an async function where a synchronous callback is expected.
6void example() {
7 processSync(() async {
Avoid passing an async function where a synchronous callback is expected.
18 void badSetup() {
19 setup((value) async {
Avoid passing an async function where a synchronous callback is expected.
29void misuse() {
30 executeCallback((n) async {
Avoid passing an async function where a synchronous callback is expected.
41void badAction() {
42 performAction((name, count) async {
Avoid passing an async function where a synchronous callback is expected.
54 void loadBad() {
55 loadData(() async {
Avoid passing an async function where a synchronous callback is expected.
64void badNamed() {
65 namedCallback(callback: () async {});

Valid

example.dartdart
// Good: passing sync function to sync parameter
void processSync(void Function() callback) {
  callback();
}

void example() {
  processSync(() {
    print('Done');
  });
}

class Handler {
  void setup(void Function(String) handler) {
    handler('test');
  }

  void goodSetup() {
    setup((value) {
      processSync(value);
    });
  }
}

void executeCallback(String Function(int) fn) {
  print(fn(42));
}

void goodUse() {
  executeCallback((n) {
    return '$n';
  });
}

// OK: async callback passed to async parameter
void processAsync(Future<void> Function() callback) async {
  await callback();
}

void asyncToAsync() {
  processAsync(() async {
    await Future.delayed(Duration(seconds: 1));
    print('Done');
  });
}

// OK: extracting async logic separately
void separated(void Function() callback) {
  callback();
}

void _asyncWork() async {
  await Future.delayed(Duration(seconds: 1));
}

void extract() {
  separated(() {
    _asyncWork(); // fire and forget (or capture result)
  });
}

// Good: passing sync callbacks to sync parameters
void performAction(void Function(String, int) callback) {
  callback('test', 42);
}

void goodAction() {
  performAction((name, count) {
    print('$name: $count');
  });
}

// Good: using named function for sync callback
class DataLoader {
  String _fetchData() {
    return 'data';
  }

  void loadData(String Function() fetcher) {
    final data = fetcher();
    print(data);
  }

  void loadGood() {
    loadData(_fetchData);
  }
}

// Good: sync arrow function
void processItems(void Function(String) handler) {
  handler('item');
}

void goodProcess() {
  processItems((item) => print('Processing: $item'));
}

void shadowedCallee() {
  void processSync(Future<void> Function() callback) {}
  processSync(() async {});
}

void namedAsync({required Future<void> Function() callback}) {}

void goodNamed() {
  namedAsync(callback: () async {});
}

Configure avoid-passing-async-when-sync-expected

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "suspicious": {
        "avoid-passing-async-when-sync-expected": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/suspicious/avoid-passing-async-when-sync-expected: <reason>