Deybi Tabora Paz
Deybi Tabora Paz

Reputation: 301

Connection closed before full header was received http post in flutter

I'm having problems trying to consume my API, and after following up on this problem I'm stuck in the matter and I've tried different emulators in various versions and the problem persists.

Error:

DioError [DioErrorType.other]: HttpException: Connection closed before full header was received, uri = http://10.0.2.2:7108/Users/authenticate

Flutter doctor

enter image description here

Http Post

class AuthenticateRemoteApi extends AuthenticateGateway {
  final AuthenticateMapper _authenticateMapper = AuthenticateMapper();

  @override
  Future<SesionUser> login(Authenticate user) async {
    var dio = Dio();
    dio.options.headers['content-Type'] = 'application/json';
    String url = 'http://10.0.2.2:7108/Users/authenticate';

    try {
      Response response = await dio.post(url, data: authenticateModelToJson(user));
      return _authenticateMapper.fromMap(jsonDecode(response.data));
    } catch (e) {
      throw Exception(e);
    }
  }
}

Upvotes: 3

Views: 12664

Answers (3)

Hoang Phuc
Hoang Phuc

Reputation: 122

In my case this error always occurs when I build app on emulator, rarely appears on real device. If you are using Android Studio, try with Pixel 6 API 33.

Upvotes: 0

Amr
Amr

Reputation: 158

I have came with this work around by creating this interceptor.

The idea of it is when encountering this random error just to retry the request.

/// Interceptor
class RetryOnConnectionChangeInterceptor extends Interceptor {
  final Dio dio;

  RetryOnConnectionChangeInterceptor({
    required this.dio,
  });

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) async {
  if (_shouldRetryOnHttpException(err)) {
      try {
        handler.resolve(await DioHttpRequestRetrier(dio: dio).requestRetry(err.requestOptions).catchError((e) {
          handler.next(err);
        }));
      } catch (e) {
        handler.next(err);
      }
    } else {
      handler.next(err);
    }

  }

  bool _shouldRetryOnHttpException(DioError err) {
    return err.type == DioErrorType.other &&
        ((err.error is HttpException && err.message.contains('Connection closed before full header was received')));
  }
}

/// Retrier
class DioHttpRequestRetrier {
  final Dio dio;

  DioHttpRequestRetrier({
    required this.dio,
  });

  Future<Response> requestRetry(RequestOptions requestOptions) async {
    return dio.request(
      requestOptions.path,
      cancelToken: requestOptions.cancelToken,
      data: requestOptions.data,
      onReceiveProgress: requestOptions.onReceiveProgress,
      onSendProgress: requestOptions.onSendProgress,
      queryParameters: requestOptions.queryParameters,
      options: Options(
        contentType: requestOptions.contentType,
        headers: requestOptions.headers,
        sendTimeout: requestOptions.sendTimeout,
        receiveTimeout: requestOptions.receiveTimeout,
        extra: requestOptions.extra,
        followRedirects: requestOptions.followRedirects,
        listFormat: requestOptions.listFormat,
        maxRedirects: requestOptions.maxRedirects,
        method: requestOptions.method,
        receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
        requestEncoder: requestOptions.requestEncoder,
        responseDecoder: requestOptions.responseDecoder,
        responseType: requestOptions.responseType,
        validateStatus: requestOptions.validateStatus,
      ),
    );
  }
}

Usage: add this interceptor [RetryOnConnectionChangeInterceptor] to your Dio client instance

Upvotes: 7

Eduardo Yamauchi
Eduardo Yamauchi

Reputation: 849

I think this could be a package bug, usually appears when the user doesn't has internet connect. Reported in #1269 and #377 issue from the package repository. I recommend you to use another package.

Upvotes: 0

Related Questions