{"record":{"id":"a089a1124ff9988d","repo":"jackwener/OpenCLI","slug":"err-message-err-a089a1","errorCode":null,"errorMessage":"字幕获取失败: ${err?.message || err}","messagePattern":"字幕获取失败: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":111,"sourceCode":"         }\n\n         try {\n             const subJson = JSON.parse(text);\n             // B站真实返回格式是 { font_size: 0.4, font_color: \"#FFFFFF\", background_alpha: 0.5, background_color: \"#9C27B0\", Stroke: \"none\", type: \"json\" , body: [{from: 0, to: 0, content: \"\"}] }\n             if (Array.isArray(subJson?.body)) return { success: true, data: subJson.body };\n             if (Array.isArray(subJson)) return { success: true, data: subJson };\n             return { error: 'UNKNOWN_JSON', data: subJson };\n         } catch (e) {\n             return { error: 'PARSE_FAILED', text: text.substring(0, 100) };\n         }\n      })()\n    `;\n        let items;\n        try {\n            items = await page.evaluate(fetchJs);\n        }\n        catch (err) {\n            throw new CommandExecutionError(`字幕获取失败: ${err?.message || err}`);\n        }\n        if (items?.error) {\n            throw new CommandExecutionError(`字幕获取失败: ${items.error}${items.text ? ' — ' + items.text : ''}`);\n        }\n        if (!items || typeof items !== 'object' || items.success !== true) {\n            throw new CommandExecutionError('字幕获取结果对象不符合预期格式');\n        }\n        const finalItems = items.data;\n        if (!Array.isArray(finalItems)) {\n            throw new CommandExecutionError('解析到的字幕列表对象不符合数组格式');\n        }\n        if (finalItems.length === 0) {\n            throw new EmptyResultError('bilibili subtitle', '字幕文件中没有字幕片段。');\n        }\n        // 5. 数据映射\n        return finalItems.map((item, idx) => {\n            const from = Number(item?.from);\n            const to = Number(item?.to);","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L93-L129","documentation":"A CommandExecutionError thrown when the in-page fetch of the subtitle CDN JSON file throws — the browser-side evaluate() rejected. The library wraps any page.evaluate failure and rethrows with the underlying message. This is about the network fetch of the subtitle file, not the earlier API call.","triggerScenarios":"page.evaluate(fetchJs) rejects: network failure reaching the CDN URL, CORS/blocked fetch inside the page context, page navigated/closed mid-evaluate, or the browser context was destroyed.","commonSituations":"Expired CDN signed URLs (subtitle_url tokens expire); offline/proxy network issues; browser tab closed by timeout; CDN returning errors that surface as fetch rejection (rare, usually fetch resolves with res.ok false).","solutions":["Re-run the command to get a fresh subtitle_url — CDN tokens expire.","Check network connectivity / proxy settings affecting Chrome.","Increase browser/CLI timeouts if the page is being torn down mid-fetch.","If persistent, verify the URL manually in Chrome and check for HTTP error status."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: confirm Chrome can reach the CDN host before the run:\nawait fetch('https://api.bilibili.com/x/web-interface/nav', { method: 'HEAD' }).catch(() => { throw new Error('network unavailable'); });","typeGuard":null,"tryCatchPattern":"try {\n  await run('bilibili subtitle', { url });\n} catch (e) {\n  if (/字幕获取失败/.test(e.message)) {\n    await sleep(5000);\n    return run('bilibili subtitle', { url }); // fresh token, fresh fetch\n  }\n  throw e;\n}","preventionTips":["Re-run promptly — subtitle_url CDN tokens expire.","Keep the automated browser page open for the whole command.","Verify proxy/network reachability for bilibili CDN hosts.","Add exponential backoff around the CLI call."],"tags":["network","fetch","bilibili","subtitle","cdp"],"backgroundTag":"fetch-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}