{"record":{"id":"f3260a2e2e1cdea2","repo":"jackwener/OpenCLI","slug":"error-f3260a","errorCode":null,"errorMessage":"等待抖音封面处理完成超时","messagePattern":"等待抖音封面处理完成超时","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/draft.js","lineNumber":210,"sourceCode":" */\nasync function waitForCoverReady(page) {\n    let lastPanelText = '';\n    let sawBusy = false;\n    for (let attempt = 0; attempt < COVER_READY_WAIT_ATTEMPTS; attempt += 1) {\n        const panelText = await getCoverCheckPanelText(page);\n        const busy = panelText.includes('检测中');\n        const ready = (panelText.includes('重新检测')\n            || panelText.includes('横/竖双封面缺失'));\n        if (busy) {\n            sawBusy = true;\n        }\n        if (sawBusy && ready && !busy) {\n            return;\n        }\n        lastPanelText = panelText;\n        await page.wait({ time: 0.5 });\n    }\n    throw new CommandExecutionError('等待抖音封面处理完成超时', lastPanelText || 'unknown');\n}\n/**\n * Click the draft button on the composer page and extract the current creation id.\n */\nasync function clickSaveDraft(page) {\n    const result = (await page.evaluate(`() => {\n    const extractCreationId = () => {\n      const titleInput = Array.from(document.querySelectorAll('input')).find(\n        (el) => (el.placeholder || '').includes('填写作品标题')\n      );\n      if (!(titleInput instanceof HTMLInputElement)) return '';\n\n      const fiberKey = Object.keys(titleInput).find((key) => key.startsWith('__reactFiber$'));\n      let fiber = fiberKey ? titleInput[fiberKey] : null;\n      while (fiber) {\n        const props = fiber.memoizedProps;\n        if (typeof props?.creation_id === 'string' && props.creation_id) {\n          return props.creation_id;","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/draft.js#L192-L228","documentation":"waitForCoverReady polls the quick-check panel up to 20 times (0.5s apart) waiting for Douyin's cover detection to first show '检测中' (busy) and then land on a ready state ('重新检测' or '横/竖双封面缺失'). If that busy→ready transition is not observed within ~10 seconds it throws this CommandExecutionError with the last panel text as detail.","triggerScenarios":"Passing --cover and the cover-detection pipeline never completes: detection takes longer than 10s, the panel text changes to new wording the ready check doesn't recognize, or the panel text never appears at all (panelText stays '').","commonSituations":"Slow server-side cover analysis; Douyin renamed '重新检测'/'检测中' copy in a UI update; very large cover image slowing processing; detection panel only rendered after user scroll.","solutions":["Read the error detail (last panel text) — if it shows a warning like '横/竖双封面缺失', provide a cover image that satisfies dimension requirements","Retry; transient slow detection may complete on a second run","Use a smaller/standard-ratio cover image (e.g. 16:9 or 9:16 JPEG) to speed detection","If panel copy changed, update stateTexts/ready checks in buildCoverCheckPanelTextJs (clis/douyin/draft.js:166) and waitForCoverReady (draft.js:199)"],"exampleFix":"// before\nif (sawBusy && ready && !busy) return;\n// after: accept completion without busy phase (fast cache hit)\nif ((sawBusy || panelText.includes('快速检测')) && ready && !busy) return;","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await opencli.douyin.draft({ video, title, cover });\n} catch (e) {\n  if (e.message.includes('等待抖音封面处理完成超时')) {\n    // read detail panel text; if '横/竖双封面缺失' fix the image, else retry\n  }\n}","preventionTips":["Use cover images meeting Douyin's horizontal/vertical cover requirements","Prefer small, standard-ratio images so detection completes quickly","Update ready-state keywords ('重新检测' etc.) when Douyin rewords the panel"],"tags":["douyin","timeout","cover","browser-automation"],"backgroundTag":"page-load-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}