micropython / micropython-lib

Core Python libraries ported to MicroPython
Other
2.3k stars 981 forks source link

urequests.get in Micropython randomly results in OSError 103 and 104 as well as ValueError #785

Open nanowiz opened 6 months ago

nanowiz commented 6 months ago

I am using urequest.get in Micropython running on a Raspberry Pi PICO W in a loop containing the following to access Ecobee's server for my furnace status:

url = "https://api.ecobee.com/1/thermostatSummary?format=json&body={\"selection\":{\"selectionType\":\"registered\",\"selectionMatch\":\"\",\"includeEquipmentStatus\":true}}"
headers = {
        'Content-Type': 'text/json',
        'Authorization': f'Bearer {accessToken}'
}
response = urequests.get(url, headers=headers)
rstatus = response.status_code
data = response.json()
response.close()

This works most of the time, but the code will randomly crash with either OSError 104 or OSError 103 or ValueError. The following are REPL outputs of these errors.

Traceback (most recent call last): File "", line 157, in File "", line 52, in furnaceStatus File "requests/init.py", line 180, in get File "requests/init.py", line 125, in request OSError: -104

Traceback (most recent call last): File "", line 166, in File "", line 52, in furnaceStatus File "requests/init.py", line 180, in get File "requests/init.py", line 130, in request ValueError: HTTP error: BadStatusLine: []

I understand that the OSError 104 and 103 are network response issues. It would be much better if they can be handled with a returned status code rather than causing an OSError. According to the githib code at line 130 of request in requests/init.py, it is complaining about an invalid response presumabily from the internet response. Again, it would be more desirable to be handled with a status code response rather than causing a program crash.

ned-pcs commented 5 months ago

OSError 104 is ECONNRESET. Which can be caused by one end or the other closing a socket too soon. But one should usually enclose network functions in try/except blocks anyway:

url = "https://api.ecobee.com/1/thermostatSummary?format=json&body={\"selection\":{\"selectionType\":\"registered\",\"selectionMatch\":\"\",\"includeEquipmentStatus\":true}}"
headers = {
        'Content-Type': 'text/json',
        'Authorization': f'Bearer {accessToken}'
}
try:
    response = urequests.get(url, headers=headers)
    rstatus = response.status_code
    data = response.json()
    response.close()
except OSError, ValueError:
    data = None
    rstatus = 500
nanowiz commented 5 months ago

Hi Ned,

Thanks for the reply. I am already doing that and catching the OSError so I can restart. OCError 104 is not too bad, but sometimes I get OSError 103 which occasionally can become sticky, where every following urequest.get call will get the OSError 103. I increased the calls to gc.collect() to free up memory in my loop. It reduced the frequency of these errors, but they still pop up once every few hours and within a day, it will turn sticky. Only way out was to do a machine.reset() and restart the program after a soft boot.

It would be much easier to handle if urequest.get just returned with a status code indicating the error instead of crashing with an exception 103 or 104.

Sammy

On Thu, Jan 18, 2024 at 3:14 PM Ned Konz @.***> wrote:

OSError 104 is ECONNRESET. Which can be caused by one end or the other closing a socket too soon. But one should usually enclose network functions in try/except blocks anyway:

url = "https://api.ecobee.com/1/thermostatSummary?format=json&body={\"selection\":{\"selectionType\":\"registered\",\"selectionMatch\":\"\",\"includeEquipmentStatus\":true}}"headers = { 'Content-Type': 'text/json', 'Authorization': f'Bearer {accessToken}' }try: response = urequests.get(url, headers=headers) rstatus = response.status_code data = response.json() response.close()except OSError, ValueError: data = None rstatus = 500

— Reply to this email directly, view it on GitHub https://github.com/micropython/micropython-lib/issues/785#issuecomment-1899366761, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOBUR45SMZETAHI3OAVQYI3YPGUGRAVCNFSM6AAAAABBOA546CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJZGM3DMNZWGE . You are receiving this because you authored the thread.Message ID: @.***>