Skip to content

QQBot stops reconnecting after failed reconnect leaves websocket closed #17703

@hoaresky

Description

@hoaresky

Summary

The QQBot adapter can stop reconnecting after a failed reconnect attempt if the previous websocket object remains present but closed.

What happens

After a QQBot websocket disconnect, the reconnect path may fail transiently while fetching a fresh gateway URL, for example during a DNS or network outage:

WebSocket error: WebSocket closed
Reconnecting in 2s (attempt 1)...
Reconnect failed: Failed to get QQ Bot gateway URL: [Errno 8] nodename nor servname provided, or not known

After that, the adapter may remain disconnected indefinitely. Subsequent sends only report that the platform is not connected, but no further reconnect attempts are made.

Root cause

QQAdapter._read_events() only raises when self._ws is missing. If self._ws is still assigned but already closed, the read loop condition is false and the method returns normally:

if not self._ws:
    raise RuntimeError("WebSocket not connected")

while self._running and self._ws and not self._ws.closed:
    ...

That normal return makes _listen_loop() treat the read as a clean exit, reset reconnect bookkeeping, and skip the exception path that would call _reconnect() again.

Expected behavior

A closed websocket should be treated as a disconnected state. _read_events() should raise so _listen_loop() continues through the existing reconnect path.

Reproduction

A minimal reproduction is to set adapter._ws to a websocket-like object where closed == True and call _read_events() while the adapter is running. The method currently returns without raising, which prevents the listener from continuing reconnect handling.

Fix

Raise RuntimeError("WebSocket closed") when _read_events() is entered with an already-closed websocket object. Add a regression test to make sure closed-but-present websocket objects cannot be treated as a clean read termination.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/gatewayGateway runner, session dispatch, deliveryplatform/qqbotQQ Bot adaptersweeper:implemented-on-mainSweeper: behavior already present on current maintype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions