Skip to content

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 #840

@Murtagy

Description

@Murtagy

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions