DIYgod/RSSHub · error · Error
Failed to fetch data from API
Error message
Failed to fetch data from API
What it means
Generic Error from a catch block wrapping got.post to the BNU (Beijing Normal University) faculty CMS API. Any thrown network/HTTP error is swallowed and re-thrown as this generic message, hiding the original cause. It signals the POST to fe.bnu.edu.cn's column listing endpoint could not complete.
Source
Thrown at lib/routes/bnu/fe.ts:41
async function handler(ctx) {
const { category } = ctx.req.param();
const apiUrl = 'https://fe.bnu.edu.cn/pc/cmscommon/nlist';
let response;
try {
// 发送 POST 请求
response = await got.post(apiUrl, {
headers: {
Accept: 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
Origin: 'https://fe.bnu.edu.cn',
Referer: 'https://fe.bnu.edu.cn/pc/cms1info/list/1/18',
'X-Requested-With': 'XMLHttpRequest',
},
body: `columnid=${category}&page=1`, // POST 数据
});
} catch {
throw new Error('Failed to fetch data from API');
}
const jsonData = JSON.parse(response.body);
// 检查返回的 code
if (jsonData.code !== 0 || !jsonData.data) {
throw new Error('Invalid API response');
}
const list = jsonData.data.map((item) => ({
title: item.title,
link: `https://fe.bnu.edu.cn/html/1/news/${item.htmlpath}/n${item.newsid}.html`,
pubDate: parseDate(item.happendate, 'YYYY-MM-DD'),
}));
const out = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
const response = await got(item.link);
const $ = load(response.data);View on GitHub (pinned to bed535e087)
Solutions
- Retry — campus CMS endpoints are intermittently flaky.
- Verify https://fe.bnu.edu.cn is reachable from the RSSHub host (curl the apiUrl with the same headers).
- If persistent, inspect the original error by temporarily logging it in the catch (the bare `catch {}` currently swallows it).
- Update the Referer/Origin/X-Requested-With headers if the CMS changed its CSRF checks.
Example fix
// before
} catch {
throw new Error('Failed to fetch data from API');
}
// after (preserve the cause for diagnosis)
} catch (e) {
throw new Error('Failed to fetch data from API: ' + (e instanceof Error ? e.message : String(e)));
} Defensive patterns
Strategy: retry
Validate before calling
try {
response = await got.post(apiUrl, { headers, body: `columnid=${category}&page=1` });
} catch (e) {
throw new Error('Failed to fetch data from API: ' + (e instanceof Error ? e.message : String(e)));
} Try / catch
// Wrap with a bounded retry for transient campus-network failures:
let response, lastErr;
for (let i = 0; i < 3; i++) {
try { response = await got.post(apiUrl, { headers, body }); break; }
catch (e) { lastErr = e; await delay(500 * (i + 1)); }
}
if (!response) throw new Error('Failed to fetch data from API: ' + lastErr); Prevention
- Do not swallow the original error in a bare catch — include its message.
- Campus CMS endpoints are flaky; add a short retry with backoff.
- Verify reachability from the RSSHub host (firewall/geo) before assuming a code bug.
When it happens
Trigger: got.post to the apiUrl threw — connection reset, DNS failure, non-2xx status that got treats as an error, or a socket timeout. The catch (no binding) discards the original error and throws the generic string.
Common situations: The BNU site is down or rate-limiting; the server IP is blocked by the campus firewall; TLS/cert issues; the hardcoded Referer/Origin headers being rejected after a site change.
Related errors
- 日报数据不存在或为空
- Invalid API response
- api error
- Failed to fetch channel data from Castbox
- Failed to fetch episode list from Castbox
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/8b58207f5c4ebe71.
Report an issue: GitHub.