{"record":{"id":"1e65de648e55da47","repo":"jackwener/OpenCLI","slug":"err-message-err-1e65de","errorCode":null,"errorMessage":"获取视频播放信息失败: ${err?.message || err}","messagePattern":"获取视频播放信息失败: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":50,"sourceCode":"        }\n        if (view?.code !== 0) {\n            throw new CommandExecutionError(`获取视频信息失败: ${view?.message ?? 'unknown'} (${view?.code})`);\n        }\n        // --page 给定时用该集 cid（selectVideoPart 越界抛错）；缺省取整集默认 cid（P1，旧行为）。\n        const cid = selectedPage != null ? selectVideoPart(view?.data, selectedPage).cid : view?.data?.cid;\n        if (!cid) {\n            throw new CommandExecutionError(`无法从 view API 拿到 cid (bvid=${bvid})`);\n        }\n        // 2. 用带 Wbi 签名的 player/v2 拿字幕列表（之前 evaluate 里 fetch 因为没签名会 403）\n        let payload;\n        try {\n            payload = await apiGet(page, '/x/player/wbi/v2', {\n                params: { bvid, cid },\n                signed: true,\n            });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`获取视频播放信息失败: ${err?.message || err}`);\n        }\n        if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n            throw new CommandExecutionError('获取到的视频播放信息对象不符合预期格式');\n        }\n        if (payload.code !== 0) {\n            throw new CommandExecutionError(`获取视频播放信息失败: ${payload.message} (${payload.code})`);\n        }\n        const needLoginSubtitle = payload.data?.need_login_subtitle === true;\n        const subtitles = payload.data?.subtitle?.subtitles;\n        if (!Array.isArray(subtitles)) {\n            throw new CommandExecutionError('获取到的字幕列表对象不符合数组格式');\n        }\n        if (subtitles.length === 0) {\n            if (needLoginSubtitle) {\n                throw new AuthRequiredError('bilibili.com', 'Bilibili subtitles are hidden behind login for this video. Please log in to bilibili.com in Chrome and retry.');\n            }\n            throw new EmptyResultError('bilibili subtitle', '此视频没有发现外挂或智能字幕。');\n        }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L32-L68","documentation":"Wrapping error: the Wbi-signed call to /x/player/wbi/v2 (which returns the subtitle list for a bvid+cid) threw, so the underlying transport error is re-thrown as CommandExecutionError prefixed with 获取视频播放信息失败. Distinct from 437, which handles the API answering with an error code; this fires only when apiGet rejects (network, timeout, signature failure producing a transport-level exception).","triggerScenarios":"apiGet(page, '/x/player/wbi/v2', {params:{bvid,cid}, signed:true}) rejects — network drop, page context closed, Wbi signing failure, or non-JSON response.","commonSituations":"Wbi keys rotated/expired in the session; unstable network or proxy; page was navigated away/closed mid-command; heavy rate limiting causing connection resets.","solutions":["Read the inner message after the prefix for the real cause (timeout vs network vs signature)","Re-establish the browser session and retry — Wbi signing depends on a live page","Retry after a short delay if rate limiting is suspected","Check network/proxy stability to api.bilibili.com"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await run(['bilibili', 'subtitle', bvid]);\n} catch (e) {\n  const m = String(e.message);\n  if (m.startsWith('获取视频播放信息失败') && !/\\(\\d+\\)/.test(m)) {\n    await sleep(2000); // then retry once; check network/session if it repeats\n  } else throw e;\n}","preventionTips":["Keep the attached Chrome session alive during the command (don't close the page)","Use a logged-in session so Wbi signing works reliably","Add retry with backoff for transient network failures"],"tags":["network","api","wbi-signature","bilibili"],"backgroundTag":"api-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}