{"record":{"id":"aa57555c1ef91c4c","repo":"jackwener/OpenCLI","slug":"from-to","errorCode":null,"errorMessage":"字幕片段缺少有效 from/to 时间戳","messagePattern":"字幕片段缺少有效 from/to 时间戳","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":131,"sourceCode":"        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',\n                to: to.toFixed(2) + 's',\n                content: String(item.content ?? '')\n            };\n        });\n    },\n});\n","sourceCodeStart":113,"sourceCodeEnd":142,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L113-L142","documentation":"A CommandExecutionError thrown during the final data mapping when a cue item in the subtitle body lacks finite numeric from/to timestamps. Each cue must have numeric start (from) and end (to) seconds to render the index/from/to/content output; malformed cues abort the whole mapping.","triggerScenarios":"A cue object in the CDN JSON body has missing, null, NaN, or non-numeric from/to — e.g. schema drift, corrupted cue entries, or items that are not objects (item is null).","commonSituations":"Bilibili changing cue field names (from/to→start/end); malformed entries in AI-generated subtitle files; hand-edited or third-party uploaded subtitle files with bad timings.","solutions":["Inspect the fetched JSON for the offending cue's actual field names.","Update the library if Bilibili renamed from/to fields.","Filter out malformed cues in a local fork/patch instead of aborting on the first bad one.","Try another subtitle track (--lang) whose file may be well-formed."],"exampleFix":"// before\nif (!item || typeof item !== 'object' || !Number.isFinite(from) || !Number.isFinite(to)) {\n  throw new CommandExecutionError('字幕片段缺少有效 from/to 时间戳');\n}\n// after\nif (!item || typeof item !== 'object' || !Number.isFinite(from) || !Number.isFinite(to)) {\n  console.warn(`跳过无效字幕片段 #${idx + 1}`);\n  return null;\n}","handlingStrategy":"validation","validationCode":"const cuesValid = (items) => Array.isArray(items) && items.every(i => i && Number.isFinite(Number(i.from)) && Number.isFinite(Number(i.to)));","typeGuard":"const isCue = (i) => !!i && typeof i === 'object' && Number.isFinite(Number(i.from)) && Number.isFinite(Number(i.to));","tryCatchPattern":"try {\n  await run('bilibili subtitle', { url });\n} catch (e) {\n  if (/from\\/to/.test(e.message)) throw new Error('Subtitle file has malformed cues; inspect raw JSON or try another track.');\n  throw e;\n}","preventionTips":["Validate cue JSON (from/to numeric) before processing.","Try another --lang track if one file is malformed.","Keep the library updated for cue field renames upstream.","Patch locally to skip bad cues instead of failing the whole batch."],"tags":["bilibili","subtitle","schema","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}