ArduinoHttpClient
ArduinoHttpClient copied to clipboard
Status: -2 or -3 stack the loop in arduino
Hi, I am using you library, it works great when i get status code: 200. But if the server send error for some reason, then i get status code -2 or -3 and then it is not send again requests to server.
Code:
#include "config.h"
#include <HttpClient.h>
#include <TinyGsmClient.h>
#ifdef DEBUG_DUMP_AT_COMMAND
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger, AM7020_RESET);
#else
TinyGsm modem(SerialAT, AM7020_RESET);
#endif
TinyGsmClient tcpClient(modem);
HttpClient httpClient = HttpClient(tcpClient, HTTP_SERVER, HTTP_PORT);
void setup() {
SerialMon.begin(MONITOR_BAUDRATE);
SerialAT.begin(AM7020_BAUDRATE);
httpClient.connectionKeepAlive();
nbConnect();
}
void callAgain() {
static unsigned long timer = 0;
char buff[100];
int state_code;
String body;
if (!modem.isNetworkConnected()) {
nbConnect();
}
//if (millis() >= timer) {
// timer = millis() + UPLOAD_INTERVAL;
/* Get Most Recent Data */
SerialMon.println(F("HTTP Get..."));
sprintf(buff, "/%s", HTTP_API);
httpClient.get(buff);
state_code = httpClient.responseStatusCode();
body = httpClient.responseBody();
SerialMon.print(F("GET state code = "));
SerialMon.println(state_code);
SerialMon.print(F("body = "));
SerialMon.println(body);
/* Create Data */
/*SerialMon.println(F("HTTP Post..."));
sprintf(buff, "/%s", HTTP_API);
httpClient.post(buff, "application/json", "{\"value\": \"POST\"}");
state_code = httpClient.responseStatusCode();
body = httpClient.responseBody();
SerialMon.print(F("POST state code = "));
SerialMon.println(state_code);
SerialMon.print(F("body = "));
SerialMon.println(body);*/
//}
}
void loop() {
callAgain();
delay(100);
}
void nbConnect(void) {
SerialMon.println(F("Initializing modem..."));
while (!modem.init() || !modem.nbiotConnect(APN, BAND)) {
SerialMon.print(F("."));
}
SerialMon.print(F("Waiting for network..."));
while (!modem.waitForNetwork()) {
SerialMon.print(F("."));
}
SerialMon.println(F(" success"));
}
We have run into the same issue. From what I can tell reading the library's code, this is what is happening:
- We try reading the response status code with
responseStatusCode()
. - For some reason, this reaches timeout (-3). Not sure why this is happening in our case, but I assume it could be attributed to an unstable internet connection? (If anyone knows more about this, please let me know)
- The state of the library is now at "reading status code". Because of this,
post()
returns the error specifying that it has been called in an unexpected state (-2). This is because instartRequest
, the state is reset in some cases (if (iState == eReadingBody || iState == eReadingChunkLength || iState == eReadingBodyChunk)
), but since iState iseReadingStatusCode
, it is not reset, resulting in an early return with -2.
Is there a good reason as to why the state is only reset in those three cases? Might simply adding an || iState == eReadingStatusCode
solve the problem, or will that have other unexpected side effects? (Or am I wrong in my reconstruction altogether?)
@roysG did you perhaps find another way to solve or work around the issue?
We did find a very simple workaround: simply construct new HttpClient
objects before each post
rather than keeping a global HttpClient object.
I actually think that this is generally more sensible: HTTP is stateless, so keeping a global (stateful) HttpClient
object is error-prone and logically inconsistent. It might be better practice to create the object on-the-fly and keep them only for as long as the code depends on that request and its result.