Skip to content

Asyncio stream doesn't handle exceptions in callback #110894

Closed
@LasseBlaauwbroek

Description

@LasseBlaauwbroek

Bug report

Bug description:

Consider the following server that always just crashes:

import asyncio

async def handle_echo(reader, writer):
    raise Exception("I break everything")

async def main():
    server = await asyncio.start_server(
        handle_echo, '127.0.0.1', 8888)
    async with server:
        await server.serve_forever()

asyncio.run(main(), debug=True)

Together with the following client:

import asyncio

async def tcp_echo_client(message):
    reader, writer = await asyncio.open_connection(
        '127.0.0.1', 8888)

    data = await reader.read(100)
    print(data)
    writer.close()
    await writer.wait_closed()
    print("closed")

asyncio.run(tcp_echo_client('Hello World!'), debug=True)

When running this in Python 3.8, the server prints a Task exception was never retrieved message with an exception. I guess this is acceptable. However, the connection is never closed, and the client is kept hanging. That should not happen in my opinion.

Furthermore, in newer Python versions, due to #96323, the internal task is being kept alive indefinitely. Therefore, the Task exception was never retrieved message is only printed when you kill the server. Otherwise, the failure is completely silent. This is extremely counter-intuitive behavior.

CPython versions tested on:

3.11

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Labels

3.11only security fixes3.12only security fixes3.13bugs and security fixestopic-asynciotype-bugAn unexpected behavior, bug, or error

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions