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.

Nirali Patel

Written by Nirali Patel

Nirali Patel is a dedicated Flutter developer with over two years of experience, specializing in creating seamless mobile applications using Dart. With a passion for crafting user-centric solutions, Nirali combines technical proficiency with innovative thinking to push the boundaries of mobile app development.

Leave a comment

Your email address will not be published. Required fields are marked *

Discuss Your Project

Connect with Flutter Agency's proficient skilled team for your app development projects across different technologies. We'd love to hear from you! Fill out the form below to discuss your project.

Have Project For Us

Get in Touch

"*" indicates required fields

ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields