{"record":{"id":"af283ea4d633520d","repo":"DIYgod/RSSHub","slug":"error-fetching-academic-information-error","errorCode":null,"errorMessage":"Error fetching academic information: ${error}","messagePattern":"Error fetching academic information: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/xbmu/academic.ts","lineNumber":73,"sourceCode":"                            description: content,\n                            category: ['university'],\n                            guid: item.link,\n                            id: item.link,\n                            image: 'http://210.26.0.114:9090/mdxg/img/weex/default_img.jpg',\n                            content,\n                            updated: item.date,\n                            language: 'zh-CN',\n                        };\n                    })\n                )\n            )) as DataItem[],\n            allowEmpty: true,\n            language: 'zh-CN',\n            feedLink: 'https://rsshub.app/xbmu/academic',\n            id: 'https://rsshub.app/xbmu/academic',\n        };\n    } catch (error) {\n        throw new Error(`Error fetching academic information: ${error}`, { cause: error });\n    }\n};\n\nexport const route: Route = {\n    path: '/academic',\n    name: '学术信息',\n    maintainers: ['PrinOrange'],\n    handler,\n    categories: ['university'],\n    features: {\n        requireConfig: false,\n        requirePuppeteer: false,\n        antiCrawler: false,\n        supportBT: false,\n        supportPodcast: false,\n        supportScihub: false,\n    },\n    example: '/xbmu/academic',","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/xbmu/academic.ts#L55-L91","documentation":"Catch-all wrapping the entire /xbmu/academic handler. Any failure — initial list fetch, per-item detail fetch, cheerio parsing, cache write — is re-thrown with an 'Error fetching academic information:' prefix and the original attached via { cause: error }.","triggerScenarios":"got(BASE_URL) or got(item.link) raises (network/HTTP error), or cheerio/load throws on malformed HTML, caught at academic.ts:72-74.","commonSituations":"xbmu.edu.cn is down or returning non-HTML (a redirect/login page), a detail link 404s, or the campus site changed its list markup.","solutions":["Inspect error.cause for the real failure (HTTP status, parse error).","Verify https://www.xbmu.edu.cn/xwzx/xsxx.htm loads in a browser from the RSSHub host's network.","If the site moved/changed selectors, report to the maintainer (PrinOrange) — the CSS selector at academic.ts:17 may need updating."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight the source URL before the full scrape\ntry {\n    const r = await got.head('https://www.xbmu.edu.cn/xwzx/xsxx.htm', { timeout: 5000 });\n    if (r.statusCode >= 400) throw new Error(`xbmu returned ${r.statusCode}`);\n} catch (e) {\n    throw new Error('xbmu academic source unreachable');\n}","typeGuard":"function isXbmuAcademicError(e: unknown): boolean {\n    return e instanceof Error && /Error fetching academic information/i.test(e.message);\n}","tryCatchPattern":"try {\n    return await xbmuAcademicHandler();\n} catch (e) {\n    const root = isXbmuAcademicError(e) ? (e.cause ?? e) : e;\n    if (root instanceof Error && /ENOTFOUND|ETIMEDOUT|getaddrinfo/i.test(root.message)) {\n        await scheduleRetry();   // transient campus-network issue\n    }\n    throw e;\n}","preventionTips":["Inspect error.cause to separate network errors from selector drift.","Cache the list page briefly so transient blips don't fail every poll.","Add a content-type check (text/html) before cheerio load to fail fast on non-HTML responses."],"tags":["xbmu","network","error-wrapping","scraping","university"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}