Summary
In qq-botpy 1.2.1, if GET https://api.sgroup.qq.com/gateway/bot times out during startup, the HTTP layer logs the timeout and returns None. Then client.py assumes the return value is a dict and immediately indexes self._ws_ap["session_start_limit"], causing:
TypeError: 'NoneType' object is not subscriptable
Observed Flow
Startup path:
client.start()
_bot_login()
self._ws_ap = await self.api.get_ws_url()
- timeout happens in
BotHttp.request()
- timeout is logged, but no exception is raised to the caller
_bot_login() indexes self._ws_ap["session_start_limit"]
Relevant Behavior
In local source for qq-botpy 1.2.1:
botpy/http.py
- catches
asyncio.TimeoutError
- logs
请求超时,请求连接: https://api.sgroup.qq.com/gateway/bot
- returns
None
botpy/client.py
self._ws_ap = await self.api.get_ws_url()
max_async = self._ws_ap["session_start_limit"]["max_concurrency"]
Actual Failure
请求超时,请求连接: https://api.sgroup.qq.com/gateway/bot
TypeError: 'NoneType' object is not subscriptable
Expected Behavior
One of these should happen instead:
- retry transient timeout automatically
- raise a clear exception from
BotHttp.request() after retry budget is exhausted
- validate
/gateway/bot response before indexing and raise a structured startup error
Suggested Fix
At minimum:
- do not silently return
None on timeout in BotHttp.request()
- either retry or raise an exception
- in
_bot_login(), validate self._ws_ap before indexing session_start_limit
This would turn a transient network issue into a recoverable or at least diagnosable error, instead of an opaque NoneType crash.
Notes
This was observed in production usage via AstrBot 4.22.0 bundling qq-botpy 1.2.1, but the root cause appears to be in qq-botpy itself.
Summary
In
qq-botpy 1.2.1, ifGET https://api.sgroup.qq.com/gateway/bottimes out during startup, the HTTP layer logs the timeout and returnsNone. Thenclient.pyassumes the return value is a dict and immediately indexesself._ws_ap["session_start_limit"], causing:Observed Flow
Startup path:
client.start()_bot_login()self._ws_ap = await self.api.get_ws_url()BotHttp.request()_bot_login()indexesself._ws_ap["session_start_limit"]Relevant Behavior
In local source for
qq-botpy 1.2.1:botpy/http.pyasyncio.TimeoutError请求超时,请求连接: https://api.sgroup.qq.com/gateway/botNonebotpy/client.pyActual Failure
Expected Behavior
One of these should happen instead:
BotHttp.request()after retry budget is exhausted/gateway/botresponse before indexing and raise a structured startup errorSuggested Fix
At minimum:
Noneon timeout inBotHttp.request()_bot_login(), validateself._ws_apbefore indexingsession_start_limitThis would turn a transient network issue into a recoverable or at least diagnosable error, instead of an opaque
NoneTypecrash.Notes
This was observed in production usage via AstrBot
4.22.0bundlingqq-botpy 1.2.1, but the root cause appears to be inqq-botpyitself.