{"record":{"id":"11d6f8b286606e6f","repo":"jackwener/OpenCLI","slug":"errorinfo-message-code-errorinfo-co","errorCode":null,"errorMessage":"帖子访问失败: ${errorInfo.message} (code: ${errorInfo.code})","messagePattern":"帖子访问失败: (.+?) \\(code: (.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/hupu/detail.js","lineNumber":35,"sourceCode":"        },\n        {\n            name: 'replies',\n            type: 'boolean',\n            default: false,\n            help: '是否包含热门回复'\n        }\n    ],\n    columns: ['title', 'author', 'content', 'replies', 'lights', 'url'],\n    func: async (page, kwargs) => {\n        const { tid, replies: includeReplies = false } = kwargs;\n        const url = getHupuThreadUrl(tid).replace(/-1\\.html$/, '.html');\n        const data = await readHupuNextData(page, url, 'Read Hupu thread detail', {\n            expectedTid: String(tid),\n        });\n        // 检查错误信息（只有当code不是200时才报错）\n        const errorInfo = data.props.pageProps.detail_error_info;\n        if (errorInfo && errorInfo.code !== 200) {\n            throw new Error(`帖子访问失败: ${errorInfo.message} (code: ${errorInfo.code})`);\n        }\n        // 获取帖子信息\n        const thread = data.props.pageProps.detail?.thread;\n        if (!thread) {\n            throw new Error('帖子不存在或已被删除');\n        }\n        const authorName = thread.author?.puname || '未知作者';\n        const content = stripHtml(thread.content);\n        const contentPreview = content.length > 300 ? content.substring(0, 300) + '...' : content;\n        // 构建结果\n        const result = {\n            title: thread.title,\n            author: authorName,\n            content: contentPreview,\n            replies: thread.replies || 0,\n            lights: thread.lights || 0,\n            url: `https://bbs.hupu.com/${tid}.html`\n        };","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hupu/detail.js#L17-L53","documentation":"When reading a Hupu thread detail, the library parses the page's __NEXT_DATA__ payload via readHupuNextData. If the embedded detail_error_info has a code other than 200, the server-side fetch of the thread failed and the library surfaces that code and message as a plain Error.","triggerScenarios":"Fetching a thread (by tid) whose __NEXT_DATA__ contains detail_error_info.code !== 200 — e.g. the thread was removed by moderators, requires permissions, or Hupu's backend returned an error for that tid.","commonSituations":"Deleted or shadow-removed posts still indexed by search engines; region/permission-restricted threads; Hupu API degradation returning non-200 codes for valid threads; mistyped tid pointing at a nonexistent post.","solutions":["Verify the tid/URL is correct and the thread opens in a normal browser","Retry later if Hupu is having backend issues (code often transient)","Treat codes like 404/403 as 'thread unavailable' and handle gracefully in your script","If valid threads consistently fail, Hupu's __NEXT_DATA__ schema likely changed — update readHupuNextData parsing"],"exampleFix":"// before\nconst detail = await hupuDetail(tid);\n// after\nlet detail;\ntry { detail = await hupuDetail(tid); }\ncatch (e) {\n  if (/code: 404/.test(e.message)) return null; // thread gone\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"const res = await fetch(threadUrl, { method: 'HEAD' });\nif (!res.ok) skipThread(tid);","typeGuard":"function isThreadAvailable(nextData) {\n  const info = nextData?.props?.pageProps?.detail_error_info;\n  return !info || info.code === 200;\n}","tryCatchPattern":"try {\n  const d = await hupuDetail(tid);\n} catch (e) {\n  const code = e.message.match(/code: (\\d+)/)?.[1];\n  if (code === '404' || code === '403') return null; // treat as unavailable\n  throw e;\n}","preventionTips":["Validate tids before fetching; skip URLs known to be deleted","Treat non-200 codes as expected outcomes, not crashes","Rate-limit requests to avoid triggering Hupu backend errors","Periodically re-check __NEXT_DATA__ schema for error-info changes"],"tags":["hupu","scraping","next-data","thread-unavailable"],"backgroundTag":"upstream-error-code","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}