环境
- astrbot_plugin_parser:v1.5.1(
core/parsers/bilibili/login.py 与当前 main 分支 e14c0b6 一致,该文件自 8b5e71c 后未再改动)
- bilibili-api:17.4.2
- AstrBot:v4.27.5 / Python 3.12
现象
群里所有 B站视频解析报错崩溃:
Star data.plugins.astrbot_plugin_parser.main_on_message handle error: 接口返回错误代码:-101,信息:账号未登录。
但凭证实际是有效的——同一凭证手动调用 get_info() / nav 接口全部成功。生产日志中的完整 traceback 显示异常从 credential 属性内部抛出:
File ".../bilibili/login.py", line 102, in credential
哔哩哔哩凭证 check_valid 未通过(已知接口误报,跳过拦截继续使用) # ← check_valid 放行了
File ".../bilibili/login.py", line 104, in credential
if await self._credential.check_refresh():
...
bilibili_api.exceptions.ResponseCodeException: 接口返回错误代码:-101,信息:账号未登录。
即:check_valid 这关过了,下一行 check_refresh() 抛异常直接炸掉整条解析链路,报错信息「账号未登录」完全误导排障方向。
根因
两层叠加:
- bilibili-api 17.4.2 的凭证检查接口行为不稳定:
Credential.check_refresh() 对失效/被风控凭证稳定抛 ResponseCodeException(-101)(它本该返回 True/False)
Credential.check_valid() 对有效凭证也会间歇性返回 False(B站接口抽风,生产日志有实锤:同一次解析中 check_valid 告警"未通过"后,同一凭证 get_info() 成功)
login.py 两处调用均无异常处理:
_init_credential() 里 await credential.check_valid() —— 抛异常 = 插件加载后首次解析即崩
credential 属性里 await self._credential.check_refresh() —— 每次解析都会走到,抛异常 = 所有解析崩溃
凭证过期期间,该问题表现为 100% 复现(每次解析必炸);凭证有效时表现为间歇性崩溃。
复现
容器内(bilibili-api 17.4.2)实测输出:
import asyncio
from bilibili_api import Credential
async def probe(tag, cred):
try:
print(tag, 'check_valid ->', await cred.check_valid())
except Exception as e:
print(tag, 'check_valid RAISED', type(e).__name__, str(e)[:60])
try:
print(tag, 'check_refresh ->', await cred.check_refresh())
except Exception as e:
print(tag, 'check_refresh RAISED', type(e).__name__, str(e)[:60])
asyncio.run(probe('失效凭证', Credential(sessdata='<过期的SESSDATA>', bili_jct='...', buvid3='...')))
失效凭证 check_valid -> False
失效凭证 check_refresh RAISED ResponseCodeException: 接口返回错误代码:-101,信息:账号未登录。
有效凭证多轮探测中 check_valid 也出现过 False(间歇),可对照上方生产日志。
修复建议
login.py 三处调用加异常兜底(检查接口异常时按「未通过/不需要刷新」处理,让凭证加载 fallback 和解析流程继续走,而不是炸掉):
# _init_credential()
try:
_ck_ok = await credential.check_valid()
except Exception:
_ck_ok = False
if _ck_ok:
...
# credential 属性
try:
_cv_ok = await self._credential.check_valid()
except Exception:
_cv_ok = False
if not _cv_ok:
logger.warning("哔哩哔哩凭证 check_valid 未通过(接口异常,跳过拦截继续使用)")
try:
_need_refresh = await self._credential.check_refresh()
except Exception:
_need_refresh = False
if _need_refresh:
...
本人在生产环境已按此 patch 稳定运行(失效→有效凭证切换全流程实测通过)。如需要我可以直接提 PR。
环境
core/parsers/bilibili/login.py与当前 main 分支 e14c0b6 一致,该文件自 8b5e71c 后未再改动)现象
群里所有 B站视频解析报错崩溃:
但凭证实际是有效的——同一凭证手动调用
get_info()/ nav 接口全部成功。生产日志中的完整 traceback 显示异常从credential属性内部抛出:即:
check_valid这关过了,下一行check_refresh()抛异常直接炸掉整条解析链路,报错信息「账号未登录」完全误导排障方向。根因
两层叠加:
Credential.check_refresh()对失效/被风控凭证稳定抛ResponseCodeException(-101)(它本该返回 True/False)Credential.check_valid()对有效凭证也会间歇性返回False(B站接口抽风,生产日志有实锤:同一次解析中 check_valid 告警"未通过"后,同一凭证get_info()成功)login.py两处调用均无异常处理:_init_credential()里await credential.check_valid()—— 抛异常 = 插件加载后首次解析即崩credential属性里await self._credential.check_refresh()—— 每次解析都会走到,抛异常 = 所有解析崩溃凭证过期期间,该问题表现为 100% 复现(每次解析必炸);凭证有效时表现为间歇性崩溃。
复现
容器内(bilibili-api 17.4.2)实测输出:
有效凭证多轮探测中 check_valid 也出现过
False(间歇),可对照上方生产日志。修复建议
login.py三处调用加异常兜底(检查接口异常时按「未通过/不需要刷新」处理,让凭证加载 fallback 和解析流程继续走,而不是炸掉):本人在生产环境已按此 patch 稳定运行(失效→有效凭证切换全流程实测通过)。如需要我可以直接提 PR。