Search code examples
flutterdart

How do i handle errors in Dio package


okay so im using dio package to authenticate users in my app. it works fine but i want to be able to show the error message in a toast message for the user and i have absolutely no idea how to do that. i tried printing the error but i get no response, please help me out im new to dio.

This is my code

 class Loginservice extends ILogin {
  @override
  Future<UserModel?> login(
      String username, String password, BuildContext context) async {
    @override
    SharedPreferences preferences = await SharedPreferences.getInstance();

    String api = '$baseUrl/login';

    final data = {"username": username, "pwd": password};
    final dio = Dio();
    Response response;
    response = await dio.post(api, data: data);
    if (response.statusCode == 200) {
      final body = response.data;
      var username = body['username'];
      var myToken = body['token'];
      preferences.setString('username', username);
      preferences.setBool('isLoggedIn', true);

          Navigator.push(
              context, MaterialPageRoute(builder: (context) => MainScreen()));
    
          return UserModel(
            username: username,
            token: body['token'],
          );
        } else {
          print('error');
        }
      }
    }

Solution

  • As mentioned in their docs,

    When an error occurs, Dio will wrap the Error/Exception to a DioException:

    You can wrap the call with a try/ catch to catch them.

    try {
      // 404
      await dio.get('https://api.pub.dev/not-exist');
    } on DioException catch (e) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx and is also not 304.
      if (e.response != null) {
        print(e.response.data)
        print(e.response.headers)
        print(e.response.requestOptions)
      } else {
        // Something happened in setting up or sending the request that triggered an Error
        print(e.requestOptions)
        print(e.message)
      }
    }
    

    and DioException contain these fields,

    /// The request info for the request that throws exception.
    RequestOptions requestOptions;
    
    /// Response info, it may be `null` if the request can't reach to the
    /// HTTP server, for example, occurring a DNS error, network is not available.
    Response? response;
    
    /// The type of the current [DioException].
    DioExceptionType type;
    
    /// The original error/exception object;
    /// It's usually not null when `type` is [DioExceptionType.unknown].
    Object? error;
    
    /// The stacktrace of the original error/exception object;
    /// It's usually not null when `type` is [DioExceptionType.unknown].
    StackTrace? stackTrace;
    
    /// The error message that throws a [DioException].
    String? message;
    

    Personally, I would use a switch statement to catch all the DioExceptionType s and handle/ return error messages accordingly.

    if (error is DioException) {
          switch (error.type) {
            case DioExceptionType.connectionTimeout:
            case DioExceptionType.receiveTimeout:
            case DioExceptionType.sendTimeout:
              networkFailure = const NetworkFailure.requestTimeout();
              break;
            case DioExceptionType.badCertificate:
              networkFailure = const NetworkFailure.badCertificate();
        ...
    

    you can find all the exception types here or you can simply go to the plugin source in your flutter app.