Skip to content

Commit 229f44d

Browse files
GH-110894: Call loop exception handler for exceptions in client_connected_cb (#111601)
Call loop exception handler for exceptions in `client_connected_cb` of `asyncio.start_server` so that applications can handle it.
1 parent 794dff2 commit 229f44d

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

Lib/asyncio/streams.py

+12
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,19 @@ def connection_made(self, transport):
245245
res = self._client_connected_cb(reader,
246246
self._stream_writer)
247247
if coroutines.iscoroutine(res):
248+
def callback(task):
249+
exc = task.exception()
250+
if exc is not None:
251+
self._loop.call_exception_handler({
252+
'message': 'Unhandled exception in client_connected_cb',
253+
'exception': exc,
254+
'transport': transport,
255+
})
256+
transport.close()
257+
248258
self._task = self._loop.create_task(res)
259+
self._task.add_done_callback(callback)
260+
249261
self._strong_reader = None
250262

251263
def connection_lost(self, exc):

Lib/test/test_asyncio/test_streams.py

+28
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,34 @@ async def inner(httpd):
10961096

10971097
self.assertEqual(messages, [])
10981098

1099+
def test_unhandled_exceptions(self) -> None:
1100+
port = socket_helper.find_unused_port()
1101+
1102+
messages = []
1103+
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
1104+
1105+
async def client():
1106+
rd, wr = await asyncio.open_connection('localhost', port)
1107+
wr.write(b'test msg')
1108+
await wr.drain()
1109+
wr.close()
1110+
await wr.wait_closed()
1111+
1112+
async def main():
1113+
async def handle_echo(reader, writer):
1114+
raise Exception('test')
1115+
1116+
server = await asyncio.start_server(
1117+
handle_echo, 'localhost', port)
1118+
await server.start_serving()
1119+
await client()
1120+
server.close()
1121+
await server.wait_closed()
1122+
1123+
self.loop.run_until_complete(main())
1124+
1125+
self.assertEqual(messages[0]['message'],
1126+
'Unhandled exception in client_connected_cb')
10991127

11001128

11011129
if __name__ == '__main__':
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Call loop exception handler for exceptions in ``client_connected_cb`` of :func:`asyncio.start_server` so that applications can handle it. Patch by Kumar Aditya.

0 commit comments

Comments
 (0)