Skip to content

Commit 5ef1cb8

Browse files
Log unservicable response errors on HTTPServer
1 parent 2ffb0ba commit 5ef1cb8

2 files changed

Lines changed: 55 additions & 2 deletions

File tree

cheroot/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ def _serve_unservicable(self):
18881888
# We can't just raise an exception because that will kill this
18891889
# thread, and prevent 503 errors from being sent to future
18901890
# connections.
1891-
self.server.error_log(
1891+
self.error_log(
18921892
repr(ex),
18931893
level=logging.ERROR,
18941894
traceback=True,

cheroot/test/test_server.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for the HTTP server."""
22

3+
import logging
34
import os
45
import pathlib
56
import queue
@@ -20,7 +21,12 @@
2021
from pypytools.gc.custom import DefaultGc
2122

2223
from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM, bton, ntob
23-
from ..server import IS_UID_GID_RESOLVABLE, Gateway, HTTPServer
24+
from ..server import (
25+
IS_UID_GID_RESOLVABLE,
26+
Gateway,
27+
HTTPServer,
28+
_STOPPING_FOR_INTERRUPT,
29+
)
2430
from ..testing import (
2531
ANY_INTERFACE_IPV4,
2632
ANY_INTERFACE_IPV6,
@@ -127,6 +133,53 @@ def test_stop_interrupts_serve():
127133
assert not serve_thread.is_alive()
128134

129135

136+
def test_serve_unservicable_logs_simple_response_errors(monkeypatch):
137+
"""Check errors while sending 503 responses are logged by the server."""
138+
error_log_calls = []
139+
140+
class BrokenRequest:
141+
def __init__(self, server, conn):
142+
self.server = server
143+
self.conn = conn
144+
145+
def simple_response(self, status):
146+
assert status == '503 Service Unavailable'
147+
raise RuntimeError('response failed')
148+
149+
class FakeConnection:
150+
linger = False
151+
152+
def __init__(self):
153+
self.closed = False
154+
155+
def close(self):
156+
self.closed = True
157+
158+
def error_log(msg='', level=20, traceback=False):
159+
error_log_calls.append((msg, level, traceback))
160+
161+
httpserver = HTTPServer(
162+
bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT),
163+
gateway=Gateway,
164+
)
165+
httpserver.ready = True
166+
httpserver.error_log = error_log
167+
168+
fake_conn = FakeConnection()
169+
httpserver._unservicable_conns.put(fake_conn)
170+
httpserver._unservicable_conns.put(_STOPPING_FOR_INTERRUPT)
171+
172+
monkeypatch.setattr('cheroot.server.HTTPRequest', BrokenRequest)
173+
174+
httpserver._serve_unservicable()
175+
176+
assert error_log_calls == [
177+
("RuntimeError('response failed')", logging.ERROR, True),
178+
]
179+
assert fake_conn.linger
180+
assert fake_conn.closed
181+
182+
130183
@pytest.mark.parametrize(
131184
'exc_cls',
132185
(

0 commit comments

Comments
 (0)