DEV Community

Cover image for Easy Way to Create a Good Error-Handling in Flutter with Dartz
Aditya Rohman
Aditya Rohman

Posted on

Easy Way to Create a Good Error-Handling in Flutter with Dartz

As developers, our main task is to create applications to solve certain problems. When published, the application we develop may produce some errors in front of the user. For example, maybe our users enter data incorrectly, the connection is lost, or even our server is down.

A good application will be able to handle the error and can point the user on the right path again. We certainly don’t want just because the app can’t handle minor errors like lost connection, the user decides to uninstall it.

In this article, I will show how to create good error handling in a Flutter project using Dartz.

Implementation

First things first, we need to figure out what errors are possible that will happen. In a login flow, for example, the common error is:

  • User inputs wrong password or email not registered
  • The server maybe had a problem
  • Lost internet connection

Now, let’s add the package that we need to the pubspec.yaml file:

...
dependencies:
    flutter:
        sdk: flutter

    dartz: ^0.10.1
    ...
Enter fullscreen mode Exit fullscreen mode

Inside the Dartz package, we will use something called Either<L,R> class. This class will be used to return 2 different things in a function.

/// Create variety of exceptions
/// Enum to help create conditions
enum LoginFailure { invalidCredentials, error }

/// Repository
/// This class can be consumed by controller, provider, or other state management later
class SomeRepository {
  final http.Client _client;

  Future<Either<LoginFailure, bool>> login(String email, String password) async {
    final _response = await _client.post(
      Uri.parse(Urls.nowPlayingMovies),
      body: {'email': email, 'password': password}
    );

    if (_response.statusCode == 201) {
      return Right(true);
    } else if (_response.statusCode == 400) {
      return Left(LoginFailure.invalidCredentials);
    } else {
      return Left(LoginFailure.error);
    }
  }

  ...
}
Enter fullscreen mode Exit fullscreen mode

There is a function with the type Future<Either<LoginFailure, bool>>. With that type, now I can return 2 different things out of that function. When the request is successful (with status code 200), boolean true will be returned as the right value. If a request failed, I can easily handle it by returning the enum as the left value. The enum class act as a helper to create conditions.

And this is the way we consume the login function, for example in a controller:

class SomeController {
  Future login(String email, String password) async {
    final _result = await _repository.login(email, password);
    _result.fold(
      (l) {
        /// Handle left
        /// For example: show dialog or alert
      },
      (r) {
        /// Handle right
        /// For example: navigate to home page
      },
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Now you can create some user interactions like this.

Example user interactions to handle some errors

Recap

So, that's the way to implement a good error-handling on Flutter. The term good means our app has more rich error-handling to help the user understand if there is something wrong when they use the app.

Thanks for reading. I hope these short tips can help you write a more clean, concise, and robust codebase for your Flutter project.

If you find this article helpful, please leave some reaction badges for me, if you don’t mind. Also, follow me to get updates about my latest articles in the future.

Discussion (0)