{"record":{"id":"1fe9d2cddede7bcb","repo":"jackwener/OpenCLI","slug":"err-message-err","errorCode":null,"errorMessage":"获取视频信息失败: ${err?.message || err}","messagePattern":"获取视频信息失败: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":31,"sourceCode":"        { name: 'lang', required: false, help: '字幕语言代码 (如 zh-CN, en-US, ai-zh)，默认取第一个' },\n        { name: 'page', required: false, help: '分P 选集序号（从 1 开始）。多 P 视频取该集字幕；缺省取默认 P1' },\n    ],\n    columns: ['index', 'from', 'to', 'content'],\n    func: async (page, kwargs) => {\n        if (!page)\n            throw new CommandExecutionError('Browser session required for bilibili subtitle');\n        const bvid = await resolveBvid(kwargs.bvid);\n        const selectedPage = parsePageArg(kwargs.page);\n        // 1. 通过 view API 拿 cid。\n        //    以前的实现走 page.goto(/video/<bvid>) + window.__INITIAL_STATE__.videoData.cid，\n        //    bangumi 绑定的 bvid（番剧/纪录片/电影/综艺）页面 state 不在 videoData 而在 epList，\n        //    导致 SELECTOR 错。view API 接受任何 bvid（UGC + PGC 都通），且不依赖 DOM 结构。\n        let view;\n        try {\n            view = await apiGet(page, '/x/web-interface/view', { params: { bvid } });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`获取视频信息失败: ${err?.message || err}`);\n        }\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) {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L13-L49","documentation":"Wrapping error: the call to Bilibili's /x/web-interface/view API (which resolves bvid -> video metadata incl. cid) threw, so the original network/transport error is re-thrown as CommandExecutionError prefixed with 获取视频信息失败. The underlying cause is embedded via err?.message. This is thrown only when apiGet itself fails (network, timeout, non-JSON response), not when the API returns an error code (that hits error 433).","triggerScenarios":"apiGet(page, '/x/web-interface/view', {params:{bvid}}) rejects: network failure, timeout, HTML returned instead of JSON, Wbi/page session broken, or DNS/proxy issues.","commonSituations":"No network or blocked access to api.bilibili.com; corporate proxy; bvid unresolved invalid causing page navigation fetch path failure; page session expired mid-command; rate limiting returning HTML interstitial.","solutions":["Check network connectivity/proxy settings to api.bilibili.com and retry","Verify the bvid/URL resolves (open it in a browser); an invalid bvid can surface here","Refresh/re-establish the browser session and cookies, then retry","Inspect the inner message after the prefix — it contains the real cause and fix accordingly"],"exampleFix":null,"handlingStrategy":"try-catch","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    // transport failure — check network/proxy, then retry with backoff\n  } else throw e;\n}","preventionTips":["Ensure stable connectivity to api.bilibili.com (check proxies/VPN)","Validate the bvid/URL before invoking","Add retry-with-backoff around network-dependent CLI calls"],"tags":["network","api","bilibili","error-wrapping"],"backgroundTag":"api-request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}