When the user(client) closes the connection the defer.CancelledError may interrupt any await operation.
This makes the code in API like
try:
do_work()
except Exception:
raise APIError()
to cause logs such as
Unhandled Error Processing Request.
Traceback (most recent call last):
...
located here
|
if not failure.check(defer.CancelledError): # pragma: no branch |
I would consider calling the user-defined callbacks still on a an exception on a finished request.
Although the error handler can not or should not write any response down - some other handled behaviour might be done.
I was emulating this locally with this code snippet
import socket
from urllib.parse import urlparse
url = 'http://127.0.0.1:8000/'
def emulate_abrupt_disconnect(url: str) -> None:
parsed_url = urlparse(url)
host = parsed_url.hostname
port = parsed_url.port or 80
path = parsed_url.path + ('?' + parsed_url.query if parsed_url.query else '')
request = (
f"GET {path} HTTP/1.1\r\n"
f"Host: {host}\r\n"
"User-Agent: PythonSocketClient/1.0\r\n"
"Connection: close\r\n"
"\r\n"
)
with socket.create_connection((host, port), timeout=5) as sock:
sock.sendall(request.encode('utf-8'))
# Abruptly close the socket without reading the response
sock.shutdown(socket.SHUT_RDWR)
sock.close()
emulate_abrupt_disconnect(url)