fix(qqbot): add is_reconnect param to QQAdapter.connect for gateway reconnect compat

The base adapter's  signature was updated to include
, which the reconnect watcher passes as
 during reconnection. All other platform adapters were
updated, but QQAdapter was missed, causing:

    TypeError: QQAdapter.connect() got an unexpected keyword argument 'is_reconnect'

This leads to an infinite retry loop since every reconnect attempt fails
immediately with the same TypeError.

Fix: add  to QQAdapter.connect()'s signature.
QQBot has no server-side update queue, so the flag is accepted only for
interface conformance.

Test: new test_connect_accepts_is_reconnect_param verifies both
adapter.connect() and adapter.connect(is_reconnect=True) succeed without
raising.
This commit is contained in:
luxuguang-leo 2026-06-26 16:04:05 +08:00 committed by Teknium
parent a7f65e3bcd
commit 276542c729
2 changed files with 25 additions and 2 deletions

View file

@ -278,8 +278,16 @@ class QQAdapter(BasePlatformAdapter):
# Connection lifecycle
# ------------------------------------------------------------------
async def connect(self) -> bool:
"""Authenticate, obtain gateway URL, and open the WebSocket."""
async def connect(self, *, is_reconnect: bool = False) -> bool:
"""
Authenticate, obtain gateway URL, and open the WebSocket.
Args:
is_reconnect: False on a cold first boot; True when the
reconnect watcher is re-establishing this platform after
an outage. QQBot has no server-side update queue so this
flag is accepted for interface conformance only.
"""
if not AIOHTTP_AVAILABLE:
message = "QQ startup failed: aiohttp not installed"
self._set_fatal_error("qq_missing_dependency", message, retryable=True)

View file

@ -190,6 +190,21 @@ class TestVoiceAttachmentSSRFProtection:
assert kwargs.get("follow_redirects") is True
assert kwargs.get("event_hooks", {}).get("response") == [_ssrf_redirect_guard]
def test_connect_accepts_is_reconnect_param(self):
"""connect() must accept is_reconnect for interface conformance with
the base adapter, which the reconnect watcher calls with
is_reconnect=True."""
from gateway.platforms.qqbot import QQAdapter
adapter = QQAdapter(_make_config(app_id="a", client_secret="b"))
adapter._ensure_token = mock.AsyncMock(side_effect=RuntimeError("stop after client init"))
# Both forms must not raise TypeError.
connected_default = asyncio.run(adapter.connect())
connected_explicit = asyncio.run(adapter.connect(is_reconnect=True))
assert connected_default is False
assert connected_explicit is False
# ---------------------------------------------------------------------------
# WebSocket proxy handling