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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions