Skip to content

Commit 9aa8829

Browse files
[3.12] GH-110894: Call loop exception handler for exceptions in client_connected_cb (GH-111601) (#111632)
Call loop exception handler for exceptions in `client_connected_cb` of `asyncio.start_server` so that applications can handle it.. (cherry picked from commit 229f44d)
1 parent 99f0dd8 commit 9aa8829

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

Lib/asyncio/streams.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,19 @@ def connection_made(self, transport):
244244
res = self._client_connected_cb(reader,
245245
self._stream_writer)
246246
if coroutines.iscoroutine(res):
247+
def callback(task):
248+
exc = task.exception()
249+
if exc is not None:
250+
self._loop.call_exception_handler({
251+
'message': 'Unhandled exception in client_connected_cb',
252+
'exception': exc,
253+
'transport': transport,
254+
})
255+
transport.close()
256+
247257
self._task = self._loop.create_task(res)
258+
self._task.add_done_callback(callback)
259+
248260
self._strong_reader = None
249261

250262
def connection_lost(self, exc):

Lib/test/test_asyncio/test_streams.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,35 @@ def test_eof_feed_when_closing_writer(self):
10741074

10751075
self.assertEqual(messages, [])
10761076

1077+
def test_unhandled_exceptions(self) -> None:
1078+
port = socket_helper.find_unused_port()
1079+
1080+
messages = []
1081+
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
1082+
1083+
async def client():
1084+
rd, wr = await asyncio.open_connection('localhost', port)
1085+
wr.write(b'test msg')
1086+
await wr.drain()
1087+
wr.close()
1088+
await wr.wait_closed()
1089+
1090+
async def main():
1091+
async def handle_echo(reader, writer):
1092+
raise Exception('test')
1093+
1094+
server = await asyncio.start_server(
1095+
handle_echo, 'localhost', port)
1096+
await server.start_serving()
1097+
await client()
1098+
server.close()
1099+
await server.wait_closed()
1100+
1101+
self.loop.run_until_complete(main())
1102+
1103+
self.assertEqual(messages[0]['message'],
1104+
'Unhandled exception in client_connected_cb')
1105+
10771106

10781107
if __name__ == '__main__':
10791108
unittest.main()
Lines changed: 1 addition & 0 deletions
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)