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 de database.
CodePudding user response:
Welcome to StackOverflow.
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:
- Try to replicate the problem with Postman. If you can the problem is definitely not related to your Flutter code.
- 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. If you know that the backend is not to blame please update us.
CodePudding user response:
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();
}
}