`BaseHTTPRequestHandler` hides `TimeoutError` from `handle_error()`
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 35/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Veraltet
- Tech-Stack
- python
- Bereich
- backend, networking
Rechercherichtung
Beginne mit BaseHTTPRequestHandler und dem im Issue beschriebenen Request-Handling-Pfad und reproduziere dann den bereitgestellten Testfall, um zu beobachten, welche TimeoutError-Ausnahmen handle_error() erreichen. Erledigt ist die Aufgabe, wenn vom Handler ausgelöste Timeouts über handle_error() gemeldet werden, ohne das bestehende Timeout-Verhalten des Request-Sockets zu verlieren.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Bug report
If anything in your method handlers (e.g. do_GET()) ends up throwing a TimeoutError, then that unhandled exception is never forwarded to handle_error(), and hence you do not get a chance to do whatever reporting you have set up there.
The cause of this is an undocumented timeout handling that was added in bpo-6267. It blindly assumes that any TimeoutError must come from the request socket and that it was requested and hence expected. That is not the case for any mildly complex request handler that might communicate with other services.
The timeline for this issue is:
?.? to 2.6: No exceptions are hidden from handle_error()
2.7 to 3.2: recv() and send() timeouts are hidden. Other timeouts, e.g. connect(), are not.
3.3 to 3.9: Same situation, but by pure luck since socket.timeout was not converted to TimeoutError yet
3.10: All timeouts are hidden, not just for recv() and send()
Your environment
- CPython versions tested on: 2.7.18, 3.2.3, 3.5.10, 3.10.7
- Operating system and architecture: Debian 7 x86_64 and Fedora 35 x86_64
Test case
This test case should give the output:
Got error!
Got error!
But instead gives:
127.0.0.1 - - [25/Nov/2022 13:48:49] Request timed out: TimeoutError(110, 'Connection timed out')
127.0.0.1 - - [25/Nov/2022 13:48:50] Request timed out: TimeoutError('timed out')
For 3.9 or older you get a mix.
Code: (change simulate if you want to have the actual socket code throw the exceptions)
#!/usr/bin/python3
import os
import errno
import socket
import threading
from time import sleep
try:
from http.server import HTTPServer, BaseHTTPRequestHandler
except ImportError:
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
simulate = True
class ConnectRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
if simulate:
raise socket.error(errno.ETIMEDOUT, "Timeout")
else:
socket.create_connection(("1.2.3.4", 9000))
class RecvRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
if simulate:
raise socket.timeout(errno.ETIMEDOUT, "Timeout")
else:
(sock, dummy) = socket.socketpair()
sock.settimeout(1)
while sock.recv(1024):
pass
class Server(HTTPServer):
def handle_error(self, request, client_address):
print("Got error!")
def run_connect_server():
s = Server(("127.0.0.1", 8998),
ConnectRequestHandler)
s.handle_request()
def run_recv_server():
s = Server(("127.0.0.1", 8999),
RecvRequestHandler)
s.handle_request()
threading.Thread(target=run_connect_server).start()
threading.Thread(target=run_recv_server).start()
sleep(0.5)
s = socket.create_connection(("127.0.0.1", 8998))
s.send(b'GET / HTTP/1.0\r\n\r\n')
while s.recv(1024):
pass
s.close()
s = socket.create_connection(("127.0.0.1", 8999))
s.send(b'GET / HTTP/1.0\r\n\r\n')
while s.recv(1024):
pass
s.close()
sleep(0.5)
Linked PRs
- gh-99806
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 36k
- Ø Merge
- 1 T. 9 Std.
- Gemergte PRs (30 T.)
- 558
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus python/cpython
-
docs pending
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
stdlib type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
stdlib type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
-
build type-bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
-
stdlib topic-email type-feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
bancolombia/sentinel#23 ·
-
test md OffenCI
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
langchain-ai/deepagents#6450 ·
-
bug client
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100