Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status: -2 or -3 stack the loop in arduino #105

Open
roysG opened this issue May 3, 2021 · 2 comments
Open

Status: -2 or -3 stack the loop in arduino #105

roysG opened this issue May 3, 2021 · 2 comments
Labels
type: imperfection Perceived defect in any part of project

Comments

@roysG
Copy link

roysG commented May 3, 2021

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"));
}
@roysG roysG changed the title Status: -2 or -3 stack the loop Status: -2 or -3 stack the loop in arduino May 3, 2021
@kb173
Copy link

kb173 commented Dec 30, 2022

We have run into the same issue. From what I can tell reading the library's code, this is what is happening:

  1. We try reading the response status code with responseStatusCode().
  2. 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)
  3. 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 in startRequest, the state is reset in some cases (if (iState == eReadingBody || iState == eReadingChunkLength || iState == eReadingBodyChunk)), but since iState is eReadingStatusCode, 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?

@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Jan 1, 2023
@kb173
Copy link

kb173 commented Jan 18, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

3 participants