{"record":{"id":"0b03aad13b57ec02","repo":"jackwener/OpenCLI","slug":"error-0b03aa","errorCode":null,"errorMessage":"帖子不存在或已被删除","messagePattern":"帖子不存在或已被删除","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/hupu/detail.js","lineNumber":40,"sourceCode":"            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        };\n        // 如果需要包含回复，添加回复信息到内容中\n        if (includeReplies) {\n            const replyList = data.props.pageProps.detail?.lights || [];\n            const topReplies = replyList.slice(0, 3);\n            if (topReplies.length > 0) {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hupu/detail.js#L22-L58","documentation":"After the error-info check passes (code 200), the library expects data.props.pageProps.detail.thread to hold the thread object. When it is absent the thread effectively does not exist or was deleted, so this Error is thrown instead of returning partial data.","triggerScenarios":"detail_error_info.code === 200 (no explicit error) but pageProps.detail.thread is undefined — the thread payload is missing entirely from __NEXT_DATA__.","commonSituations":"Recently deleted threads where the error code still says 200; soft-removed/审核中 posts; Hupu A/B layout changes moving thread data to a different prop path; cached pages whose data was pruned.","solutions":["Confirm the thread still exists by opening its URL in a browser","Retry after a short delay — freshly deleted or under-review posts may transiently lack the thread payload","If this happens for all threads, inspect __NEXT_DATA__ in a browser and update the detail/thread extraction path in clis/hupu/detail.js"],"exampleFix":"// before\nconst thread = data.props.pageProps.detail?.thread;\n// after\nconst thread = data.props.pageProps.detail?.thread\n  ?? data.props.pageProps.threadInfo?.thread;\nif (!thread) throw new Error('帖子不存在或已被删除');","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasThread(nextData) {\n  return Boolean(nextData?.props?.pageProps?.detail?.thread);\n}","tryCatchPattern":"try {\n  const d = await hupuDetail(tid);\n} catch (e) {\n  if (e.message === '帖子不存在或已被删除') return null;\n  throw e;\n}","preventionTips":["Check the thread URL in a browser before treating absence as a bug","Handle 'deleted thread' as a normal result in batch jobs","Re-verify the detail/thread prop path after Hupu frontend updates","Add a short retry for freshly posted/deleted threads where data may lag"],"tags":["hupu","scraping","missing-data","deleted-content"],"backgroundTag":"missing-payload-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}