{"record":{"id":"99cd8a038412ca95","repo":"jackwener/OpenCLI","slug":"error-99cd8a","errorCode":null,"errorMessage":"字幕获取结果对象不符合预期格式","messagePattern":"字幕获取结果对象不符合预期格式","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":117,"sourceCode":"             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);\n            if (!item || typeof item !== 'object' || !Number.isFinite(from) || !Number.isFinite(to)) {\n                throw new CommandExecutionError('字幕片段缺少有效 from/to 时间戳');\n            }\n            return {\n                index: idx + 1,\n                from: from.toFixed(2) + 's',","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L99-L135","documentation":"A CommandExecutionError thrown when page.evaluate returns a result that is not an object with success === true. The in-page fetch script is expected to resolve to { success: true, data: [...] }; anything else (null, undefined, non-object, or success flag absent/false) triggers this guard.","triggerScenarios":"page.evaluate resolves to null/undefined (page navigated away, serialization failure), or the injected script's shape changed / an unhandled branch returned something unexpected.","commonSituations":"Browser page navigated or was recycled during evaluate; very large subtitle payloads hitting serialization limits; a CLI/library bug or an outdated injected script after API changes.","solutions":["Retry — transient page/serialization issues often resolve on a second run.","Ensure the browser page stays open (no navigation) while the command runs.","Update the library in case the injected fetch script needs to match new API behavior.","If payloads are huge, check Chrome's structured-clone/serialization limits in the automation setup."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isFetchResult = (r) => !!r && typeof r === 'object' && r.success === true && Array.isArray(r.data);","tryCatchPattern":"try {\n  await run('bilibili subtitle', { url });\n} catch (e) {\n  if (/不符合预期格式/.test(e.message)) {\n    await sleep(3000);\n    return run('bilibili subtitle', { url }); // page may have navigated; retry\n  }\n  throw e;\n}","preventionTips":["Prevent page navigation during command execution.","Avoid concurrent automation on the same browser tab.","Retry once on this error — often a transient evaluate/serialization issue.","Update the library if the injected script needs fixing."],"tags":["bilibili","subtitle","schema","cdp","serialization"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}