How to Handle Error With Bloc Pattern In Flutter ?

· 4 min read
How to Handle Error With Bloc Pattern In Flutter
How to Handle Error With Bloc Pattern In Flutter

Bloc works by receiving events and emitting states. It doesn’t care from where the event came from. using the same example from the above, the view would signal an event to the bloc/controller with “hey, my number changed!”, the bloc then would process this new event and, if suitable, emit a signal to the UI: “hey UI! You should change! I have a new state for you!”. Then, the UI rebuilds itself to present those changes. So in this article, we will go through How to Handle Error With Bloc Pattern In Flutter.

You can also read our article for Which Pattern to Choose From MVVM and Bloc.

How to Handle Error With Bloc Pattern In Flutter?

First, we build our main page (The navigation root) like this:

@override
 Widget build(BuildContext context) {
   return BlocBuilder<SuspectEvent, SuspectState>(
       bloc: _bloc,
       builder: (context, state) {
         if (state.cameras.isEmpty) _bloc.dispatch(GetCamerasEvent());

         if (!_isExceptionHandled) {
           _shouldHandleException(
               hasException: state.hasException,
               handleException: state.handleException);
         }
       return Scaffold(
  ...

We declare the _shouldHandleException like this (still on the main page):

_shouldHandleException(
    {@required bool hasException, @required Exception handleException}) {
  if (hasException) {
    if (handleException is AuthenticationException) {
      _isExceptionHandled = true;
      SchedulerBinding.instance.addPostFrameCallback((_) async {
        InfoDialog.showMessage(
                context: context,
                infoDialogType: DialogType.error,
                text: 'Please, do your login again.',
                title: 'Session expired')
            .then((val) {
          Navigator.popUntil(context, ModalRoute.withName('/'));
          this._showLogin();
        });
      });
    } else if (handleException is BusinessException) {
      _isExceptionHandled = true;
      SchedulerBinding.instance.addPostFrameCallback((_) async {
        InfoDialog.showMessage(
                context: context,
                infoDialogType: DialogType.alert,
                text: handleException.toString(),
                title: 'Verify your fields')
            .then((val) {
          _bloc.dispatch(CleanExceptionEvent());
          _isExceptionHandled = false;
        });
      });
    } else {
      _isExceptionHandled = true;
      SchedulerBinding.instance.addPostFrameCallback((_) async {
        InfoDialog.showMessage(
                context: context,
                infoDialogType: DialogType.error,
                text: handleException.toString(),
                title: 'Error on request')
            .then((val) {
          _bloc.dispatch(CleanExceptionEvent());
          _isExceptionHandled = false;
        });
      });
    }
  }
}

On our block we have:

@override
Stream<SuspectState> mapEventToState(SuspectEvent event) async* {
  try {
    if (event is GetCamerasEvent) {

      ... //(our logic)
      yield (SuspectState.newValue(state: currentState)
        ..cameras = _cameras
        ..suspects = _suspects);
    }
    ... //(other events)
  } catch (error) {
    yield (SuspectState.newValue(state: currentState)
      ..hasException = true
      ..handleException = error);
  }
}

In our error handling the InfoDialog is just a showDialog and it gets on top of any route. So the alert just needed to be called on the root route.

You can access the BLoC in the initState() method if you wrap it in a scheduleMicrotask method so that it runs after the initState() method completed:

@override
void initState() {
  super.initState();
  // Do initialization here.
  scheduleMicrotask(() {
    // Do stuff that uses the BLoC here.
  });
}

That would allow code like this:

Future<void> login() {
  try {
    // Do the network stuff, like logging the user in or whatever.
    Bloc.of(context).login(userController.text, emailController.text);
  } on ServerNotReachableException {
    // Redirect the user, display a prompt or change this
    // widget's state to display an error. It's up to you.
  }
}

Conclusion:

Thanks for being with us on a Flutter Journey !!!

So in this article today, we have been through How to Handle Error With Bloc Pattern In Flutter.

Keep Learning !!! Keep Fluttering !!!

Flutter Agency is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget GuideFlutter ProjectsCode libs and etc.

Flutter Agency is one of the most popular online portals dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge of Flutter.

Leave a Reply