Skip to main content

check-is-not-closed-after-async-gap

added in: 1.4.0
Free+

Warns when an async handler does not have isClosed check before dispatching an event after an async gap.

⚙️ Config

Set additional-methods (default is empty) to add additional methods used for listening to bloc events.

analysis_options.yaml
dart_code_metrics:
rules:
- check-is-not-closed-after-async-gap:
additional-methods:
- customOn

Example

❌ Bad:

class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterIncrementEvent>(_handle);
on<CounterDecrementEvent>((event, emit) async {
emit(state + 1);
await Future.delayed(const Duration(seconds: 3));
add(CounterDecrementEvent()); // LINT: Avoid emitting an event after an await point without checking 'isClosed'.
});
}

Future<void> _handle(CounterEvent event, Emitter<int> emit) async {
emit(state + 1);
await Future.delayed(const Duration(seconds: 3));
emit(CounterDecrementEvent()); // LINT: Avoid emitting an event after an await point without checking 'isClosed'.
}
}

✅ Good:

class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterIncrementEvent>(_handle);
on<CounterDecrementEvent>((event, emit) async {
emit(state + 1);
await Future.delayed(const Duration(seconds: 3));
if (!isClosed) {
add(CounterDecrementEvent());
}
});
}

Future<void> _handle(CounterEvent event, Emitter<int> emit) async {
emit(state + 1);
await Future.delayed(const Duration(seconds: 3));
if (!isClosed) {
emit(CounterDecrementEvent());
}
}
}