DIYgod/RSSHub · error
response.message
Error message
response.message
What it means
Thrown by the ranking handler when the GET to `${apiBase}?${apiParams}` (e.g. https://api.bilibili.com/x/web-interface/ranking/v2) returns HTTP 200 with a non-zero business code. Unlike other bilibili routes it propagates `response.message` directly with no fallback, so if the upstream omits the field the thrown Error will have an empty/undefined message. A non-zero code typically means Bilibili rejected the request (risk control, web_location signature issue, or region restriction).
Source
Thrown at lib/routes/bilibili/ranking.ts:254
const rid = ctx.req.param('rid') || 'all';
const embed = !ctx.req.param('embed');
const isNumericRid = /^\d+$/.test(rid);
const { apiBase, apiParams, referer, ridChinese, link, ridType } = getAPI(isNumericRid, rid);
if (ridType.startsWith('pgc/')) {
throw new Error('This type of ranking is not supported yet');
}
const response = await ofetch(`${apiBase}?${apiParams}`, {
headers: {
Referer: referer,
origin: 'https://www.bilibili.com',
},
});
if (response.code !== 0) {
throw new Error(response.message);
}
const data = response.data || response.result;
const list = data.list || [];
return {
title: `bilibili 排行榜-${ridChinese}`,
link,
item: await Promise.all(
list.map(async (item) => {
const subtitles = isJsonFeed && !config.bilibili.excludeSubtitles && item.bvid ? await cache.getVideoSubtitleAttachment(item.bvid) : [];
return {
title: item.title,
description: utils.renderUGCDescription(embed, item.pic, item.desc || item.title, item.aid, undefined, item.bvid),
pubDate: item.ctime && parseDate(item.ctime, 'X'),
author: item.owner.name,
link: !item.ctime || (item.ctime > utils.bvidTime && item.bvid) ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,
image: item.pic,
attachments: item.bvid
? [View on GitHub (pinned to bed535e087)
Solutions
- Retry after a short cooldown — many -352/-479 responses are transient rate-limit signals.
- If you self-host, route RSSHub through a residential/cleaner IP or add the wbi signature (w_rid, wts) to apiParams as the comments at the top of ranking.ts already imply is required.
- Reduce polling frequency and avoid concurrent requests to the same ranking endpoint.
- If response.message is empty, patch the throw to include the code: `throw new Error(response.message || 'Error code ' + response.code)`.
Example fix
// before
if (response.code !== 0) {
throw new Error(response.message);
}
// after (guarantee a non-empty, actionable message)
if (response.code !== 0) {
throw new Error(response.message || `Bilibili ranking API error: code ${response.code}`);
} Defensive patterns
Strategy: retry
Validate before calling
// Soft pre-flight: probe the ranking endpoint and surface risk-control early.
import ofetch from '@/utils/ofetch';
async function rankingReachable(apiBase: string, apiParams: string) {
try {
const r = await ofetch<{ code: number }>(`${apiBase}?${apiParams}`, { headers: { Referer: 'https://www.bilibili.com/' } });
return r.code === 0;
} catch { return false; }
} Type guard
interface RankEnv<T> { code: number; message?: string; data?: T; result?: T }
function isRankOk<T>(r: RankEnv<T>): r is RankEnv<T> & { code: 0 } { return r.code === 0; } Try / catch
try {
if (response.code !== 0) throw new Error(response.message);
} catch (e) {
const m = (e instanceof Error ? e.message : '') || '';
if (m.includes('-352') || m.includes('-479') || m.includes('-799')) {
// transient anti-crawler — retry with backoff
await backoffRetry(() => ofetch(`${apiBase}?${apiParams}`, opts));
}
throw e;
} Prevention
- If you self-host, append the wbi signature (w_rid, wts) to apiParams so bilibili does not return -352/-479 for unsigned requests.
- Cache the ranking result for several minutes to avoid repeated upstream calls.
- Run RSSHub behind a non-flagged egress IP; public instances are commonly risk-controlled.
- Patch the throw to include the code so empty upstream messages stay diagnosable.
When it happens
Trigger: GET /bilibili/ranking/:rid where the ranking/v2 endpoint answers code !== 0 — commonly -352/-799 (risk control / anti-crawler) when RSSHub is rate-limited or missing the w_rid/wts wbi signature, or -479 (恶意请求) on aggressive polling.
Common situations: Public RSSHub instance IP flagged by Bilibili's anti-crawler; missing/rotated wbi signing keys; the ranking endpoint now requires a w_rid/wts pair not appended here; transient upstream error.
Related errors
- response.message ?? `Error code ${response.code}`
- response.message ?? `Error code ${response.code}`
- response.message ?? response.msg ?? `Error code ${response.c
- response.message ?? response.msg ?? `Error code ${response.c
- msgUnread.message ?? `Error code ${msgUnread.code}`
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/9c156d5adb56ff50.
Report an issue: GitHub.