{"record":{"id":"523e5d9f3007b3da","repo":"DIYgod/RSSHub","slug":"error-523e5d","errorCode":null,"errorMessage":"未能获取鱼塘数据","messagePattern":"未能获取鱼塘数据","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/jandan/utils.ts","lineNumber":78,"sourceCode":"        } as DataItem;\n    });\n\n    return { title, items };\n};\n\n/**\n * Handle the forum/bbs section (鱼塘)\n */\nexport const handleForumSection = async (rootUrl: string): Promise<{ title: string; items: DataItem[]; link: string }> => {\n    const title = '煎蛋 - 鱼塘';\n    const currentUrl = `${rootUrl}/new/forum`;\n\n    const forumId = 112928;\n    const apiUrl = `${rootUrl}/api/forum/posts/${forumId}?page=1`;\n    const forumData = await ofetch(apiUrl);\n\n    if (forumData.code !== 0) {\n        throw new Error('未能获取鱼塘数据');\n    }\n\n    const items = forumData.data.list.map(\n        (post) =>\n            ({\n                author: post.author_name,\n                title: post.title,\n                pubDate: parseDate(post.create_time),\n                updated: parseDate(post.update_time),\n                link: `${rootUrl}/new/forum/topic/${post.post_id}`,\n                category: post.reply_count > 0 ? [`${post.reply_count}条回复`] : undefined,\n            }) as DataItem\n    );\n\n    return { title, items, link: currentUrl };\n};\n\n/**","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/jandan/utils.ts#L60-L96","documentation":"Thrown by handleForumSection in the jandan (煎蛋) route when the forum '鱼塘' (bbs) API at /api/forum/posts/112928?page=1 returns a response whose numeric `code` field is not 0. The route treats code===0 as success and any other code as a total failure, surfacing a plain Error (Chinese: '未能获取鱼塘数据' = 'could not get fish-pond data'). It is a hard failure because the handler cannot build any items without forumData.data.list.","triggerScenarios":"ofetch to `${rootUrl}/api/forum/posts/112928?page=1` succeeds at the transport level but the JSON body has `code` set to a non-zero value (e.g. 1, -1, 404). Common when the hardcoded forumId 112928 was deleted/renamed by 煎蛋, when the site is rate-limiting the API, or when the API endpoint shape changed so `code` is no longer the success field.","commonSituations":"Site restructure that moves/renames the forum board; upstream API returning an error envelope while still sending HTTP 200; deploying with a stale rootUrl; transient backend outages of jandan's API.","solutions":["Verify the forumId 112928 still exists by opening https://jandan.net/api/forum/posts/112928?page=1 in a browser and checking the `code` field","If the endpoint changed, update the apiUrl template and forumId in lib/routes/jandan/utils.ts:73-74 to match the current 煎蛋 API","If code is non-zero only transiently, treat it as retryable: wrap ofetch in a retry/backoff before throwing","Log the full forumData object (not just code) in the error so the new failure mode is diagnosable"],"exampleFix":"// before\nif (forumData.code !== 0) {\n    throw new Error('未能获取鱼塘数据');\n}\n// after\nif (forumData.code !== 0 || !forumData.data?.list) {\n    throw new Error(`未能获取鱼塘数据 (code=${forumData.code}, msg=${forumData.message ?? 'n/a'})`);\n}","handlingStrategy":"try-catch","validationCode":"// Before calling handleForumSection, probe the API contract\nasync function isForumApiHealthy(rootUrl: string): Promise<boolean> {\n  try {\n    const data = await ofetch(`${rootUrl}/api/forum/posts/112928?page=1`);\n    return data?.code === 0 && Array.isArray(data?.data?.list);\n  } catch {\n    return false;\n  }\n}","typeGuard":"interface JandanForumResponse { code: number; data?: { list?: unknown[] }; message?: string }\nfunction isForumResponse(v: unknown): v is JandanForumResponse {\n  return typeof v === 'object' && v !== null && typeof (v as JandanForumResponse).code === 'number';\n}","tryCatchPattern":"try {\n  return await handleForumSection(rootUrl);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('鱼塘')) {\n    // transient API failure — retry once after backoff, then surface a friendly feed-level error\n    await new Promise((r) => setTimeout(r, 1500));\n    return await handleForumSection(rootUrl);\n  }\n  throw e;\n}","preventionTips":["Monitor the jandan forum API with a health check and alert on code!==0","Keep forumId configurable rather than hardcoded so restructures are a config change","Include the upstream code/message in thrown errors for faster triage","Decouple transport success (HTTP 200) from business success (code===0) explicitly"],"tags":["api-response","scraping","hardcoded-id"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}