OpenComputers icon indicating copy to clipboard operation
OpenComputers copied to clipboard

Internet API Throws Exception for HTTP Error Response (again)

Open kodai2199 opened this issue 2 years ago • 5 comments

I'm trying to use a REST API I built, but I cannot handle HTTP error codes in-game, because attempting to iterate over the request handle throws the following error: Server returned HTTP response code: 400 for URL: ..., and getmetatable(handle).__index.response() simply returns nil so I am unable to check for certain response codes there either.

I believe this issue was said to be fixed here https://github.com/MightyPirates/OpenComputers/issues/3398. However, in the latest version, this bug is still here. I am tempted to look at the differences between the relevant files in the latest release and in the older ones to see what's going on.

I am now using https://http.codes/ for testing purposes, and I can confirm that I can correctly get codes for responses like 200 OK. But with 400, 404, ... I only get nil, and an error if I try to read the response. Thank you in advance for your support!

kodai2199 avatar Sep 20 '23 08:09 kodai2199

For now I was able to circumvent the problem with a pretty ugly solution. I parse the response in a protected call, and if I get an error, I use string.match() to find the error code within the error message. Unfortunately the error message changes for codes 404 and 410, leaving no information on which of those two error codes was received. Since 404 is way more frequent, I decided to return 404 in that situation.

Of course a fix would be better.

function requestWithResponseCode(url, post_data, headers, method)
    local handle = internet.request(url, post_data, headers, method)
    local result = ""
    local success, error = pcall(function() for chunk in handle do result = result..chunk end end)
    if success == false and error ~= nil then
        local error_code = error:match("code: (%d%d%d) ")
        if error_code ~= nil then
            return error_code, result
        else
            return 404, result
        end
    end

   if success == true then
       local mt = getmetatable(handle)
       local code, message, headers = mt.__index.response()
       return code, result
   end
end

kodai2199 avatar Sep 20 '23 09:09 kodai2199

It was fixed, but then it was reverted as not every Minecraft configuration actually had the Apache HTTP client library, nor could I figure out in the limited maintenance time I have for the mod: https://github.com/MightyPirates/OpenComputers/commit/555ae0e695db0ae252aa153a4a8f330568c41dab

asiekierka avatar Apr 07 '24 09:04 asiekierka

The problem, I suppose, is that:

  • a bunch of programs (like wget) depend on the old behaviour to some extent (they don't check the response code at all, assuming exception = failure),
  • reading the response code requires a relatively unintuitive while not response.finishConnect() do os.sleep(0.05) end ; local code, message = response.response() call, and should probably get a friendlier API.

So this would best go into an OpenComputers 1.9.0 update; but given the mod is essentially unmaintained...

asiekierka avatar Apr 07 '24 21:04 asiekierka

@kodai2199 Hopefully this workaround will be to your satisfaction, for the time being.

asiekierka avatar Apr 13 '24 07:04 asiekierka