WesleyAlmont
WesleyAlmont

Reputation: 305

I'm not receiving response from API when making a post requisition in FLUTTER

I'm facing a strange error when I'm sending data to an API.

I have some endpoints that work pretty fine when I send and receive data. But one of those is giving me some trouble.

I'll try to explain.

So when I send a data object through the POST method using the HTTP package, the data which was sent is reaching the database and is added, but nothing is coming back from requisition.

Future postCupomFiscal(CupomFiscal cupom) async {
    log(jsonEncode(cupom.toJson()));

    var config = await LojaConfigs.iniciarConfigs();
    var url = Uri.parse('http://127.0.0.1:8082/api/v1/carga_venda');


    var client = http.Client();

    try {
      var response = await client
          .post(url,
              headers: {
                'Content-Type': 'application/json; charset=UTF-8',
                'ambiente': '${config['ambiente']}',
                'cnpj_loja': '${config['cnpj_loja']}',
                'chave_acesso': '${config['chaveacesso']}',
                'token': '${config['token']}'
              },
              body: jsonEncode(cupom.toJson()))
          .timeout(const Duration(seconds: 15));

      if (response.statusCode == 200 || response.statusCode == 201) {
        return jsonDecode(response.body);
      }
    } on SocketException {
      throw FetchDataException('Sem conexão com a Internet.');
    } on TimeoutException {
      throw FetchDataException('Tempo excedido.');
    } finally {
      client.close();
    }
    }
  }

It is expected that the response returns a JSON informing whether the data was inserted or not in the database.

Upvotes: 2

Views: 3528

Answers (3)

Josip Domazet
Josip Domazet

Reputation: 2890

First of all the error you get is error: TimeoutException after 0:00:15.000000: Future not completed. Since you state that the POST request sometimes randomly works and sometimes doesn't I suspect that the backend in some cases just requires more time to send you an answer.

To fix this you can remove the .timeout(const Duration(seconds: 15)); line.

If this does not fix it I would do this:

  1. Try to replicate the problem with Postman. If you can the problem is definitely not related to your Flutter code.
  2. Try to add/leave out some headers in the Postman request. Sometimes headers cause some ... weird behaviour.

As of now your Flutter code looks good to me.

Upvotes: 1

WesleyAlmont
WesleyAlmont

Reputation: 305

I'm really happy with the time you spent with me to find a solution to my problem. I've spoken iwth backend developer from my team and we found the problem.

When the data comes into the API the process has an UPDATE set, this process is taking more time than we expected. So while the update is not finished the API keeps freezed waiting that update conclusions and response comes back.

Sometimes this update is taking about 10s and some more than 2min.

We are looking for a solution to this UPDATE problem.

I am very grateful for your time.

Upvotes: 1

mondayrris
mondayrris

Reputation: 724

In your scenario, this may be a case the app cannot receive response randomly. The best way is to handle it well before you find a solution.

Your backend needs to add a condition to serve on retries, which is initiated by flutter package http_retry.

When an request fails, http_retry waits 500ms before the first retry, and increases the delay by 1.5x each time.

Install this package to the project:

flutter pub add http_retry

Solution with http_retry:

Future<void> httpRetries() async {
  final client = RetryClient(
    http.Client(),
    retries: 4,
    // change the statusCode with one that can fit your case. When return true, this client will retry once the request
    when: (response) =>
        response.statusCode != 200 && response.statusCode != 201,
    // whenever an error is caught, this client will retry once the request when this function returns true
    whenError: (_, stackTrace) {
      print(stackTrace);
      return true;
    },
    onRetry: (_, __, ___) => print("retry!"),
  );
  try {
    // use this as usual as a http client
    print(await client.post(Uri.parse('https://your-post-url')));
  } finally {
    client.close();
  }
}

Upvotes: 2

Related Questions