Skip to content

QueueShutDown subclass doesn't catch native asyncio.QueueShutDown on Python 3.13+ — spurious error logged on every shutdown #6756

Description

@FarhanAliRaza

Problem

On Python 3.13+, every EventProcessor.stop() logs

Error in event processor queue task during shutdown:
...
asyncio.queues.QueueShutDown

and sends the exception to telemetry, even though shutdown is working as intended.

Mechanism

(packages/reflex-base/src/reflex_base/event/processor/event_processor.py)

The compat shim defines a subclass of the native exception:

if hasattr(asyncio, "QueueShutDown"):
    class QueueShutDown(asyncio.QueueShutDown):
        ...
else:
    class QueueShutDown(Exception):
        ...

Instance checks only work one way: the local class catches itself, but the native asyncio.QueueShutDown raised by queue.get() after stop() calls self._queue.shutdown() is not an instance of the local subclass. As a result:

  • with contextlib.suppress(QueueShutDown): around the _process_queue loop does not suppress it, so the queue task dies with the native exception, and
  • in stop(), except (asyncio.CancelledError, QueueShutDown, RuntimeError): when awaiting self._queue_task doesn't match either, so the native exception falls through to except Exception, which calls telemetry.send_error(...) and console.error("Error in event processor queue task during shutdown: ...").

Pre-3.13 is unaffected (the queue is never shut down and the local class is only raised, never caught-against-native).

Fix sketch

Alias instead of subclassing when the native exception exists:

if hasattr(asyncio, "QueueShutDown"):
    QueueShutDown = asyncio.QueueShutDown
else:
    class QueueShutDown(Exception):
        ...

(or catch asyncio.QueueShutDown explicitly alongside the shim at both sites).

Found while adding drain assertions to the event-loop benchmarks in #6751.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions