{"record":{"id":"23eee717379ccb7c","repo":"jackwener/OpenCLI","slug":"failed-to-open-zhihu-answer-target-answerid","errorCode":null,"errorMessage":"Failed to open Zhihu answer ${target.answerId}: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Failed to open Zhihu answer (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/zhihu/download-helpers.js","lineNumber":150,"sourceCode":"        return {\n          title: document.querySelector('.Post-Title, h1.ContentItem-title, .ArticleTitle')?.textContent?.trim() || 'untitled',\n          author: document.querySelector('.AuthorInfo-name, .UserLink-link')?.textContent?.trim() || '',\n          publishTime: document.querySelector('.ContentItem-time, .Post-Time')?.textContent?.trim() || '',\n          ...normalized\n        };\n      })()\n    `).catch((error) => {\n        throw new CommandExecutionError(`Zhihu column extraction failed: ${error instanceof Error ? error.message : String(error)}`);\n    });\n    return requireArticle(raw);\n}\n\nexport async function extractAnswer(page, target) {\n    try {\n        await page.goto(`https://www.zhihu.com/answer/${target.answerId}`);\n    }\n    catch (error) {\n        throw new CommandExecutionError(\n            `Failed to open Zhihu answer ${target.answerId}: ${error instanceof Error ? error.message : String(error)}`,\n            'Open the answer URL in Chrome and retry after the page is reachable.',\n        );\n    }\n    const currentUrl = typeof page.getCurrentUrl === 'function' ? await page.getCurrentUrl().catch(() => '') : '';\n    const currentTarget = parseAnswerTarget(currentUrl);\n    if (!currentTarget || currentTarget.answerId !== target.answerId || !currentTarget.questionId\n        || (target.questionId && currentTarget.questionId && target.questionId !== currentTarget.questionId)) {\n        throw new CommandExecutionError(`Zhihu answer navigation changed identity for answer ${target.answerId}`);\n    }\n\n    const apiUrl = `https://www.zhihu.com/api/v4/answers/${target.answerId}?include=content,author,created_time,question,url`;\n    const normalize = `(${normalizeContentImages.toString()})`;\n    const raw = await page.evaluate(`\n      (async () => {\n        let response;\n        try {\n          response = await fetch(${JSON.stringify(apiUrl)}, { credentials: 'include' });","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zhihu/download-helpers.js#L132-L168","documentation":"extractAnswer first navigates the Browser Bridge page to https://www.zhihu.com/answer/<answerId>. If page.goto rejects — unreachable host, DNS failure, timeout, connection reset, or the bridge cannot control the tab — the error is converted to a CommandExecutionError that names the answer id and includes a remediation hint: open the URL in Chrome and retry once reachable. It fires before any scraping or API call happens.","triggerScenarios":"Calling extractAnswer(page, { answerId }) when page.goto to www.zhihu.com/answer/<id> throws: no internet/DNS failure, Zhihu unreachable or timing out, the Browser Bridge Chrome instance is closed, or the tab was killed during navigation.","commonSituations":"Developer offline or behind a proxy/firewall blocking www.zhihu.com; Chrome profile used by the bridge was closed; corporate network blocks zhihu.com; transient Zhihu outage; typo in the answer id causing an immediate connection-level failure (rare, usually gives 404 instead).","solutions":["Check network connectivity and confirm https://www.zhihu.com resolves in a browser.","Relaunch/reconnect the Chrome instance backing the Browser Bridge, then rerun the command.","Retry after a short wait — transient timeouts and connection resets are the most common cause.","If behind a proxy/firewall, allow-list www.zhihu.com or switch networks."],"exampleFix":"// before\nawait extractAnswer(page, { answerId: '12345' });\n// after\ntry {\n  await extractAnswer(page, { answerId: '12345' });\n} catch (err) {\n  if (/Failed to open Zhihu answer/.test(err.message)) {\n    await sleep(3000); // transient network/timeout — retry once\n    await extractAnswer(page, { answerId: '12345' });\n  } else throw err;\n}","handlingStrategy":"retry","validationCode":"async function canReachZhihu() {\n  try {\n    const res = await fetch('https://www.zhihu.com/robots.txt', { method: 'HEAD' });\n    return res.ok || res.status < 500;\n  } catch { return false; }\n}\nif (!(await canReachZhihu())) throw new Error('zhihu.com unreachable; fix network before extracting');","typeGuard":null,"tryCatchPattern":"try {\n  await extractAnswer(page, { answerId });\n} catch (err) {\n  if (String(err.message).startsWith('Failed to open Zhihu answer')) {\n    // network/navigation failure: backoff and retry up to N times\n    for (let i = 1; i <= 3; i++) {\n      await sleep(i * 2000);\n      try { return await extractAnswer(page, { answerId }); } catch { /* retry */ }\n    }\n  }\n  throw err;\n}","preventionTips":["Verify connectivity to www.zhihu.com before batch downloads","Keep the Bridge-controlled Chrome instance running for the whole job","Add exponential backoff retries around extractAnswer","Check proxy/firewall settings if running in a corporate environment"],"tags":["network","navigation","timeout","zhihu"],"backgroundTag":"page-navigation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}