adafruit / Adafruit_CircuitPython_Requests

Requests-like interface for web interfacing
MIT License
51 stars 36 forks source link

Catch recv-into exception to prevent Out of sockets #72

Closed anecdata closed 3 years ago

anecdata commented 3 years ago

An ETIMEDOUT exception occurring on a socket.recv_into call in a Session request would leave the socket open, and after two occurrences, would get RuntimeError: Out of sockets and require a microcontroller reset.

Traceback (most recent call last):
  File "code.py", line 675, in http_get
  File "/lib/adafruit_requests.py", line 595, in get
  File "/lib/adafruit_requests.py", line 572, in request
OSError: [Errno 116] ETIMEDOUT
# ...
Traceback (most recent call last):
  File "code.py", line 675, in http_get
  File "/lib/adafruit_requests.py", line 595, in get
  File "/lib/adafruit_requests.py", line 572, in request
OSError: [Errno 116] ETIMEDOUT
# ...
Traceback (most recent call last):  
  File "code.py", line 675, in http_get
  File "adafruit_requests.py", line 595, in get
  File "adafruit_requests.py", line 559, in request
  File "adafruit_requests.py", line 436, in _get_socket
  File "adafruit_requests.py", line 433, in _get_socket
RuntimeError: Out of sockets

After this change, if the failure persists, it will raise an OutOfRetries: exception, just as in the case of persistent _send_request failures.

brentru commented 3 years ago

@anecdata I have a question..since this eventually raises OutOfRetries if we cant obtain a socket, do we want to pass some "out of sockets" RuntimeError text to OutOfRetries? Currently it's just raising which isn't descriptive about why it failed.

anecdata commented 3 years ago

It seems to be transient timeouts that recover naturally, but more info is better. I know nothing about custom exceptions, but I'm sure I can find an example somewhere. New commit forthcoming.

anecdata commented 3 years ago

Managed to catch it in testing:

Traceback (most recent call last):
  File "code.py", line 663, in http_get
  File "/lib/adafruit_requests.py", line 598, in get
  File "/lib/adafruit_requests.py", line 583, in request
OutOfRetries: Repeated socket failures