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.
This commit is contained in:
Kumar Aditya 2023-11-02 13:08:18 +05:30 committed by GitHub
parent 794dff2fb1
commit 229f44d353
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 0 deletions

View file

@ -245,7 +245,19 @@ def connection_made(self, transport):
res = self._client_connected_cb(reader,
self._stream_writer)
if coroutines.iscoroutine(res):
def callback(task):
exc = task.exception()
if exc is not None:
self._loop.call_exception_handler({
'message': 'Unhandled exception in client_connected_cb',
'exception': exc,
'transport': transport,
})
transport.close()
self._task = self._loop.create_task(res)
self._task.add_done_callback(callback)
self._strong_reader = None
def connection_lost(self, exc):

View file

@ -1096,6 +1096,34 @@ async def inner(httpd):
self.assertEqual(messages, [])
def test_unhandled_exceptions(self) -> None:
port = socket_helper.find_unused_port()
messages = []
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
async def client():
rd, wr = await asyncio.open_connection('localhost', port)
wr.write(b'test msg')
await wr.drain()
wr.close()
await wr.wait_closed()
async def main():
async def handle_echo(reader, writer):
raise Exception('test')
server = await asyncio.start_server(
handle_echo, 'localhost', port)
await server.start_serving()
await client()
server.close()
await server.wait_closed()
self.loop.run_until_complete(main())
self.assertEqual(messages[0]['message'],
'Unhandled exception in client_connected_cb')
if __name__ == '__main__':

View file

@ -0,0 +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.