Closed haqqi closed 5 years ago
@7Kronos hi, a possible option is to use extension like this
extension BlocBaseExtension<T> on BlocBase<T> {
void maybeEmit(T state) {
if (!isClosed) emit(state);
}
}
@7Kronos hi, a possible option is to use extension like this
extension BlocBaseExtension<T> on BlocBase<T> { void maybeEmit(T state) { if (!isClosed) emit(state); } }
This produces a warning since emit
is protected
@felangel What will be the appropriate fix for this case? https://github.com/felangel/bloc/issues/120#issuecomment-1708567614
@felangel What will be the appropriate fix for this case? #120 (comment)
Below is the snippet of code in version 7 and then version 8 of the package.
Flutter Bloc Version 7.3.3
Flutter Bloc Version 8.1.4
You can see that the check for _eventController.isClosed
was removed from version 8.
My proposal would be to check that the bloc state controller is not closed as this is what my workaround uses. This is different to the event controller that was checked in version 7. There must have been a reason for the changes between 7 and 8 so I'm not sure if there are any other implications of this proposal.
@override
void add(Event event) {
// ignore: prefer_asserts_with_message
assert(() {
final handlerExists = _handlers.any((handler) => handler.isType(event));
if (!handlerExists) {
final eventType = event.runtimeType;
throw StateError(
'''add($eventType) was called without a registered event handler.\n'''
'''Make sure to register a handler via on<$eventType>((event, emit) {...})''',
);
}
return true;
}());
if (isClosed) return; // <--- This is the added line.
try {
onEvent(event);
_eventController.add(event);
} catch (error, stackTrace) {
onError(error, stackTrace);
rethrow;
}
}
One of the easiest and best approaches is to ignore such errors but print them to the console, which can be achieved with the code below:
void main() {
_handleErrors();
// runApp ...
}
// Bloc.emit state errors are ignored but they are still logged in the console.
void _handleErrors() {
FlutterError.onError = (details) {
final exception = details.exception;
if (_isBlocStateError(exception)) {
print('Bloc emit state error: $details');
return;
}
FlutterError.presentError(details);
};
PlatformDispatcher.instance.onError = (exception, stackTrace) {
if (_isBlocStateError(exception)) {
print('Bloc emit state error: $exception');
return true;
}
return false;
};
}
bool _isBlocStateError(Object exception) {
final isStateError = exception is StateError;
if (!isStateError) return false;
return exception.message == 'Cannot emit new states after calling close';
}
I got this error while trying a scenario:
await Future.delayed(Duration(seconds: 2));
in the mapEventToState bloc. Then i yield some state.Seems like it is similar with #52