Skip to content

B站凭证 check_refresh() 抛 -101 异常无兜底,导致全部解析以「账号未登录」崩溃(凭证有效时也会发生) #192

Description

@xiaoyuyu6420

环境

  • 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() 抛异常直接炸掉整条解析链路,报错信息「账号未登录」完全误导排障方向。

根因

两层叠加:

  1. bilibili-api 17.4.2 的凭证检查接口行为不稳定
    • Credential.check_refresh() 对失效/被风控凭证稳定抛 ResponseCodeException(-101)(它本该返回 True/False)
    • Credential.check_valid()有效凭证也会间歇性返回 False(B站接口抽风,生产日志有实锤:同一次解析中 check_valid 告警"未通过"后,同一凭证 get_info() 成功)
  2. 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。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions