Amine Zeroual
Amine Zeroual

Reputation: 25

Can't catch error with dio package in flutter

I'm implementing the post method using dio package and when I try to catch exceptions in dioError it won't catch any error, I use interceptor and I found that the OnError method is never called by the app.

I searched in different articles and posts but nothing specific mentioned this issue, I used dio version 4.0.2 and still have the same problem, I tried to extend the DioError in my exception file and nothing happened

The post method :

@override
  Future post(
    String path, {
    Map<String, dynamic>? body,
    bool formDataIsEnabled = false,
    Map<String, dynamic>? queryParams,
  }) async {
    try {
      debugPrint("ENTERING THE POST METHOD:");
      final response = await client.post(path,
          queryParameters: queryParams,
          data: formDataIsEnabled ? FormData.fromMap(body!) : body);
      return _handleJsonResponse(response);
    } on DioError catch (error) {
        return _handleDioError(error);
    }
  }

The handling methods :

 dynamic _handleJsonResponse(Response<dynamic> response) {
    final jsonResponse = jsonDecode(response.data);
    return jsonResponse;
  }

  dynamic _handleDioError(DioError error) {
    switch (error.type) {
      case DioErrorType.connectTimeout:
        break;
      case DioErrorType.sendTimeout:
        break;
      case DioErrorType.receiveTimeout:
        throw FetchDataException();
      case DioErrorType.response:
        switch (error.response?.statusCode) {
          case StatusCode.badRequest:
            throw BadRequestException();
          case StatusCode.unauthorized:
          case StatusCode.forbidden:
            throw UnauthorisedException();
          case StatusCode.notFound:
            throw NotFoundException();
          case StatusCode.conflict:
            throw ConflictException();
          case StatusCode.internalServerError:
            throw InternalServerErrorException();
        }
        break;
      case DioErrorType.cancel:
        break;
      case DioErrorType.other:
        throw ServerExceptions(message: "Error");
    }
  }

The interceptor:

class AppInterceptors extends Interceptor {
  @override
  Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async{
    debugPrint('REQUEST [${options.method}]=>PATH: ${options.path}');
    options.headers[AppStrings.contentType] = AppStrings.applicationContentType;
    super.onRequest(options, handler);
  }

  @override
  Future onResponse(Response response, ResponseInterceptorHandler handler)async {
    debugPrint('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
     super.onResponse(response, handler);
  }
  @override
  Future onError(DioError err, ErrorInterceptorHandler handler) async{
    debugPrint('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
   super.onError(err, handler);
  }

Upvotes: 1

Views: 2290

Answers (2)

Duy Tran
Duy Tran

Reputation: 1134

All responses from server must include a status code, by default Dio will treat a response as success if status code is in range 2xx (200 - 299), the others are error.

So every response will invoke onResponse or onError, depend on its status code.

Check ValidateStatus at BaseOptions enter image description here

E.g, if you would like an unauthorized response (with status code 401), will invoke onError, config like this

enter image description here

If onError method is never called, maybe your config method validateStatus always returns true in all cases.

Upvotes: 1

Zeeshan Ahmad
Zeeshan Ahmad

Reputation: 676

Try to check the response status after the post request. Sometimes APIs do not generate exceptions so you need to add a check on the response statusCode.

Upvotes: 1

Related Questions