-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: emitting a state in a closed Cubit throws an error #4165
Comments
Hi @ra48ad 👋 Are you able to share a link to a minimal reproduction sample illustrating the problem/inconsistency you're seeing? It'd be much easier to help if you could share a repro, thanks! |
Thank you for your reply! Sure, here are two comparable samples for a Cubit and a Bloc: Cubit class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
// delay emit to simulate async operation
void increment() => Future.delayed(
Duration(seconds: 3),
() => emit(state + 1),
);
}
void main(List<String> args) {
final cubit = CounterCubit();
cubit.increment();
cubit.close();
// prints 0, exception [StateError] thrown (bloc_base.dart line 97)
print(cubit.state);
} Bloc enum CounterEvent { increment }
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterEvent>(_onCounterEvent);
}
Future<void> _onCounterEvent(CounterEvent event, Emitter<int> emit) async {
if (event == CounterEvent.increment) {
// delay emit to simulate async operation
return Future.delayed(
Duration(seconds: 3),
() => emit(state + 1),
);
}
}
}
void main(List<String> args) {
final bloc = CounterBloc();
bloc.add(CounterEvent.increment);
bloc.close();
// prints 0, no exception thrown because of isClosed check (bloc.dart line 202)
print(bloc.state);
} As you can see, there is a (small) difference in behaviour of both, even though the code is very similar. What do you think? is there anyway to prevent the exception without adding extra checks in the Cubit? |
Why is that For example, I have a case where I downlooad the image and get its size. It is a long operation which I can break. Now I get a |
This behavior was introduced to be consistent with how |
Thank you for your kind reply! @felangel I understand this point of view and it makes sense. however, since I started using Cubits instead of Blocs in big parts of my apps, this behaviour have been a pain for me and my team. I am glad you are considering a change. Would it be ok if I make a Pull Request with the change for you to review it? |
I faced also some issues about that behavior because the bloc is still running even though it is closed which causes issues in other parts of my app. What do you think about this? @ra48ad |
Hi! 👋 I see the issue you’re pointing out. The current behavior indeed results in an error when attempting to emit a new state from a closed Cubit, especially in asynchronous functions. This behavior might be different from Bloc, where calling emit on a closed instance simply ignores the state change without throwing an error. Steps to Address This: I’d be happy to help with an update or workaround if needed. Let me know if there are any specific directions to explore! Thanks! |
What still could happen if only the emitted states are ignored that the rest of the method that handles the event, would still call functions that could result into an error. It would be nice if after the close all events are stopped or canceled. In this case also the emit would be stopped but I am not sure if Dart allows to cancel asynchronous functions @xoliq0v |
Description
Trying to emit a state when the cubit is closed (can happen for example in async functions) leads to an Error being thrown. This behaviour may be intentional, but it is - however - different from a Bloc's behaviour the emit is called.
Steps To Reproduce
Expected Behavior
Calling emit on a closed Cubit ignores the new state and throws no error (Just like a Bloc would)
Screenshots
Additional Context
The text was updated successfully, but these errors were encountered: