From d179d6e209cc2493e811a0b4189dcc5ba4806177 Mon Sep 17 00:00:00 2001 From: Andrew Dang Date: Wed, 24 Jun 2026 22:05:20 -0500 Subject: [PATCH 1/3] Fix unservicable connection error logging --- cheroot/server.py | 2 +- cheroot/test/test_server.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/cheroot/server.py b/cheroot/server.py index 284cf17c72..1a0970076d 100644 --- a/cheroot/server.py +++ b/cheroot/server.py @@ -1904,7 +1904,7 @@ def _serve_unservicable(self): # We can't just raise an exception because that will kill this # thread, and prevent 503 errors from being sent to future # connections. - self.server.error_log( + self.error_log( repr(ex), level=logging.ERROR, traceback=True, diff --git a/cheroot/test/test_server.py b/cheroot/test/test_server.py index ae6e390a44..36f8b0e735 100644 --- a/cheroot/test/test_server.py +++ b/cheroot/test/test_server.py @@ -1,5 +1,6 @@ """Tests for the HTTP server.""" +import logging import os import pathlib import queue @@ -127,6 +128,47 @@ def test_stop_interrupts_serve(): assert not serve_thread.is_alive() +def test_unservicable_conn_logs_unexpected_response_errors(monkeypatch): + """Check that unexpected 503 response errors are logged.""" + class Conn: + linger = False + close_calls = 0 + + def close(self): + self.close_calls += 1 + httpserver.ready = False + + httpserver = HTTPServer( + bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT), + gateway=Gateway, + ) + test_exception = RuntimeError('unexpected 503 response error') + conn = Conn() + log_entries = [] + + def simple_response(_request, _status): + raise test_exception + + def log_error(*args, **kwargs): + log_entries.append((args, kwargs)) + + httpserver.error_log = log_error + httpserver.ready = True + httpserver._unservicable_conns.put(conn) + monkeypatch.setattr( + 'cheroot.server.HTTPRequest.simple_response', + simple_response, + ) + + httpserver._serve_unservicable() + + assert log_entries == [ + ((repr(test_exception),), {'level': logging.ERROR, 'traceback': True}), + ] + assert conn.linger is True + assert conn.close_calls == 1 + + @pytest.mark.parametrize( 'exc_cls', ( From 92bfe01cd2429c05f43f935eb4ab29877b89d7cd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 03:27:07 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cheroot/test/test_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cheroot/test/test_server.py b/cheroot/test/test_server.py index 36f8b0e735..e3f072e6d7 100644 --- a/cheroot/test/test_server.py +++ b/cheroot/test/test_server.py @@ -130,6 +130,7 @@ def test_stop_interrupts_serve(): def test_unservicable_conn_logs_unexpected_response_errors(monkeypatch): """Check that unexpected 503 response errors are logged.""" + class Conn: linger = False close_calls = 0 From b0177b849865677706befd181b1378b289b55b6a Mon Sep 17 00:00:00 2001 From: Andrew Dang Date: Wed, 24 Jun 2026 22:05:20 -0500 Subject: [PATCH 3/3] Fix unservicable connection error logging --- cheroot/test/test_server.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/cheroot/test/test_server.py b/cheroot/test/test_server.py index e3f072e6d7..998fed1222 100644 --- a/cheroot/test/test_server.py +++ b/cheroot/test/test_server.py @@ -130,29 +130,25 @@ def test_stop_interrupts_serve(): def test_unservicable_conn_logs_unexpected_response_errors(monkeypatch): """Check that unexpected 503 response errors are logged.""" - - class Conn: - linger = False - close_calls = 0 - - def close(self): - self.close_calls += 1 - httpserver.ready = False - httpserver = HTTPServer( bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT), gateway=Gateway, ) test_exception = RuntimeError('unexpected 503 response error') - conn = Conn() + close_calls = [] log_entries = [] + def close_conn(): + close_calls.append(None) + httpserver.ready = False + def simple_response(_request, _status): raise test_exception def log_error(*args, **kwargs): log_entries.append((args, kwargs)) + conn = types.SimpleNamespace(linger=False, close=close_conn) httpserver.error_log = log_error httpserver.ready = True httpserver._unservicable_conns.put(conn) @@ -167,7 +163,7 @@ def log_error(*args, **kwargs): ((repr(test_exception),), {'level': logging.ERROR, 'traceback': True}), ] assert conn.linger is True - assert conn.close_calls == 1 + assert close_calls == [None] @pytest.mark.parametrize(