DIYgod/RSSHub · error · Error
HTTP error! status: ${res.status}
Error message
HTTP error! status: ${res.status} What it means
Unlike other routes, this path uses the native `fetch` (not `got`) to call the Fanbox `post.info` API with credentials included, and throws a generic Error echoing `res.status` on any non-OK response. The status code is the key diagnostic: 401 means the session cookie is missing/invalid, 403/451 is an access restriction, 429 is rate limiting.
Source
Thrown at lib/routes/fanbox/utils.tsx:189
return ret;
}
export function parseItem(page: Page, item: PostItem) {
return cache.tryGet(`fanbox-${item.id}-${item.updatedDatetime}`, async () => {
const postDetail: PostDetailResponse = await page.evaluate(
async ({ url }) => {
const res = await fetch(url, {
method: 'GET',
credentials: 'include',
headers: {
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site',
},
});
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
return res.json();
},
{ url: `https://api.fanbox.cc/post.info?postId=${item.id}` }
);
return {
title: item.title || 'No title',
description: await parseDetail(postDetail.body.post),
pubDate: parseDate(item.updatedDatetime),
link: `https://${item.creatorId}.fanbox.cc/posts/${item.id}`,
category: item.tags,
};
}) as Promise<DataItem>;
}
async function getSoundCloudEmbedUrl(videoId: string) {View on GitHub (pinned to bed535e087)
Solutions
- Set or refresh the FANBOX_SESSION cookie in your RSSHub config and restart.
- Read the status from the message: 401 -> auth, 429 -> back off, 5xx -> retry.
- For 429/5xx, retry with exponential backoff; for 401, do not retry until credentials are fixed.
Example fix
// before
// if (!res.ok) {
// throw new Error(`HTTP error! status: ${res.status}`);
// }
// after
// if (!res.ok) {
// if (res.status === 401) throw new Error('Fanbox session cookie is missing or expired (401)');
// if (res.status === 429) throw new Error('Fanbox rate limited (429) - retry later');
// throw new Error(`HTTP error! status: ${res.status}`);
// } Defensive patterns
Strategy: retry
Validate before calling
// Validate credentials presence before calling
if (!config.fanbox?.session) {
throw new Error('FANBOX_SESSION is not configured — expect 401 from post.info');
} Try / catch
async function fetchFanbox(url: string) {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch(url, { credentials: 'include' });
if (res.ok) return res.json();
if (res.status === 401 || res.status === 404) throw new Error(`Fanbox ${res.status}`);
// 429 / 5xx — back off and retry
await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
}
throw new Error('Fanbox request failed after retries');
} Prevention
- Distinguish 401 (fix creds) from 429/5xx (retry) before giving up.
- Refresh the session cookie on a schedule; do not let it expire silently.
- Rate-limit outbound Fanbox calls to stay under their threshold.
When it happens
Trigger: Calling post.info without a valid FANBOX_SESSION cookie (401); hitting Fanbox rate limits (429); requesting a deleted/creator-restricted post (404); a transient 5xx.
Common situations: Self-hosting without configuring the Fanbox session cookie; the cookie expired since last refresh; aggressive polling tripping rate limits.
Related errors
- 日报数据不存在或为空
- 文章列表获取失败,可能是被临时限制了访问,请稍后重试 ${JSON.stringify(resp.data)}
- 未获取到数据!
- Cannot start TG: ${err}
- Authentication failed. Access denied.\n${requestPath}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/7cc39389a399832a.
Report an issue: GitHub.