From 5ef1cb8897eb17168c82cdf1a67f6fb708e0e0d9 Mon Sep 17 00:00:00 2001 From: era Date: Thu, 11 Jun 2026 19:53:17 +0530 Subject: [PATCH 1/2] Log unservicable response errors on HTTPServer --- cheroot/server.py | 2 +- cheroot/test/test_server.py | 55 ++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/cheroot/server.py b/cheroot/server.py index 27e9173b15..e4e10616eb 100644 --- a/cheroot/server.py +++ b/cheroot/server.py @@ -1888,7 +1888,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..db30af2123 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 @@ -20,7 +21,12 @@ from pypytools.gc.custom import DefaultGc from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM, bton, ntob -from ..server import IS_UID_GID_RESOLVABLE, Gateway, HTTPServer +from ..server import ( + IS_UID_GID_RESOLVABLE, + Gateway, + HTTPServer, + _STOPPING_FOR_INTERRUPT, +) from ..testing import ( ANY_INTERFACE_IPV4, ANY_INTERFACE_IPV6, @@ -127,6 +133,53 @@ def test_stop_interrupts_serve(): assert not serve_thread.is_alive() +def test_serve_unservicable_logs_simple_response_errors(monkeypatch): + """Check errors while sending 503 responses are logged by the server.""" + error_log_calls = [] + + class BrokenRequest: + def __init__(self, server, conn): + self.server = server + self.conn = conn + + def simple_response(self, status): + assert status == '503 Service Unavailable' + raise RuntimeError('response failed') + + class FakeConnection: + linger = False + + def __init__(self): + self.closed = False + + def close(self): + self.closed = True + + def error_log(msg='', level=20, traceback=False): + error_log_calls.append((msg, level, traceback)) + + httpserver = HTTPServer( + bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT), + gateway=Gateway, + ) + httpserver.ready = True + httpserver.error_log = error_log + + fake_conn = FakeConnection() + httpserver._unservicable_conns.put(fake_conn) + httpserver._unservicable_conns.put(_STOPPING_FOR_INTERRUPT) + + monkeypatch.setattr('cheroot.server.HTTPRequest', BrokenRequest) + + httpserver._serve_unservicable() + + assert error_log_calls == [ + ("RuntimeError('response failed')", logging.ERROR, True), + ] + assert fake_conn.linger + assert fake_conn.closed + + @pytest.mark.parametrize( 'exc_cls', ( From a8a068bc3096dab0c04c90e687c0012e975ac5ea Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 14:25:51 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cheroot/test/test_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheroot/test/test_server.py b/cheroot/test/test_server.py index db30af2123..62a7191d64 100644 --- a/cheroot/test/test_server.py +++ b/cheroot/test/test_server.py @@ -22,10 +22,10 @@ from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM, bton, ntob from ..server import ( + _STOPPING_FOR_INTERRUPT, IS_UID_GID_RESOLVABLE, Gateway, HTTPServer, - _STOPPING_FOR_INTERRUPT, ) from ..testing import ( ANY_INTERFACE_IPV4,