Sleep() causes sendHttpGetRequest() to fail intermintently

  • Platform information:
    • Hardware: x86_64/amd
    • OS: debian 11.11
    • Java Runtime Environment: open jdk 17
    • openHAB version: 4.2.3-1

So I’m trying to write a script, using EMAScript, this is the reduced script I wrote. Background, I’m trying to poll a file on an HTTPS server I control.

Anyways, code:

{
  let otp_url = "https://edman007.com/";
 let http = Java.type("org.openhab.core.model.script.actions.HTTP");
  
//returns the OTP, or -1 is one after start does not exist
function getOTP(){
    for (let i = 0; i < 10; i++){
      console.log("Query...")
      let response = http.sendHttpGetRequest(otp_url, 2000);
      if (typeof response != "string"){
        console.log(typeof response)
        console.log(response)
        return "-1"
      }
      java.lang.Thread.sleep(5000);//if you comment this out it doesn't seem to cause a problem
    }
    return "no problem"
}

  
  console.log(getOTP());
}

Anyways, I very consistently get output that looks like this:

13:00:16.959 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:00:22.003 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:00:27.013 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:00:32.023 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:00:37.028 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:00:37.032 [ERROR] [penhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: java.nio.channels.AsynchronousCloseException
13:00:37.033 [INFO ] [nhab.automation.script.ui.rivian_test] - object
13:00:37.034 [INFO ] [nhab.automation.script.ui.rivian_test] - null
13:00:37.035 [INFO ] [nhab.automation.script.ui.rivian_test] - -1

Or this:

13:02:54.273 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:02:59.366 [INFO ] [nhab.automation.script.ui.rivian_test] - Query...
13:02:59.370 [ERROR] [penhab.core.model.script.actions.HTTP] - Fatal transport error: java.util.concurrent.ExecutionException: java.io.EOFException: @756bdb46::DecryptedEndPoint@37e900ba{l=/192.168.1.5:46918,r=edman007.com/54.163.210.121:443,OPEN,fill=-,flush=-,to=5004/0}
13:02:59.373 [INFO ] [nhab.automation.script.ui.rivian_test] - object
13:02:59.374 [INFO ] [nhab.automation.script.ui.rivian_test] - null
13:02:59.375 [INFO ] [nhab.automation.script.ui.rivian_test] - -1

I’ve tested this on two of my HTTPS servers, they are running apache with nothing funny, just strict HTTPS settings. This happens on both, if I change the URL to google.com it seems to actually work just fine without issue. I’m open to people saying it’s something to do with my server config, but I have done a decrypted byte dump of the connection, and the working requests are identical to the failing requests, minus some timestamps.

Is there something wrong with my script? Is there a way I can workaround it? Or is this a bug in openhab?

Maybe something with your use of let?

In addition to the above, I don’t think you need to explicitly import the http action. At least I didn’t: see section 3 of the post below:

Tried both those things, my original code was in a self invoking function, but forgot to do that for my test case, that said, using var, or a self invoking function makes no difference, still doesn’t work.

Also, wasn’t aware of the actions thing, but that too doesn’t make a difference, here is the current code, still doing the same thing:

(function(){
  let otp_url = "https://edman007.com/";
  
//returns the OTP, or -1 is one after start does not exist
function getOTP(){
    for (let i = 0; i < 10; i++){
      console.log("Query...")
      let response = actions.HTTP.sendHttpGetRequest(otp_url, 2000);
      if (typeof response != "string"){
        console.log(typeof response)
        console.log(response)
        return "-1"
      }
      java.lang.Thread.sleep(5000);
    }
    return "no problem"
}
  console.log(getOTP());
})();

I see why you need the sleep statement.
5 seconds is quite long. If you have other rules started in parallel, problems will arise such as this one.
You better create a time event triggered rule for this

The actual use case is in attempting to obtain a login token via MFA. So I need to access one server to start the login, then wait for an email to arrive (I have another server that processes it and grabs the code), then I need to get that code and pass it back through the API to get the login token.

I expect it to only run this branch once every six months. But the script needs tokens from the http API and from email. They don’t come instantly

use a state machine pattern. Assign the current state to a variable, or a virtual item state. Then you have a looping timer for retrying the current task/state, and when that task is done, advance to the next state.