mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
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:
parent
794dff2fb1
commit
229f44d353
3 changed files with 41 additions and 0 deletions
|
@ -245,7 +245,19 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
|
||||||
res = self._client_connected_cb(reader,
|
res = self._client_connected_cb(reader,
|
||||||
self._stream_writer)
|
self._stream_writer)
|
||||||
if coroutines.iscoroutine(res):
|
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 = self._loop.create_task(res)
|
||||||
|
self._task.add_done_callback(callback)
|
||||||
|
|
||||||
self._strong_reader = None
|
self._strong_reader = None
|
||||||
|
|
||||||
def connection_lost(self, exc):
|
def connection_lost(self, exc):
|
||||||
|
|
|
@ -1096,6 +1096,34 @@ os.close(fd)
|
||||||
|
|
||||||
self.assertEqual(messages, [])
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue