When a client has already closed the connection, error handlers registered with `@klein.app.Klein(...).handle_errors()` do not get invoked, and instead a traceback is always logged
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 838
- Forks
- 123
- Avg merge
- 7h 58m
- Merged PRs (30d)
- 12
Description
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 https://github.com/twisted/klein/blob/a15e4176da46fade1bae34136bdd1d65770bc27f/src/klein/_resource.py#L270
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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at src/klein/_resource.py around line 270 and reproduce the abrupt disconnect with the socket example in the issue. Trace how defer.CancelledError is handled when an await is interrupted, then verify that registered handle_errors callbacks are invoked for a finished request without producing the unhandled traceback.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100