{"record":{"id":"71e7dca97fab243c","repo":"DIYgod/RSSHub","slug":"message-code","errorCode":null,"errorMessage":"message ?? code","messagePattern":"message \\?\\? code","errorType":"exception","errorClass":null,"httpStatus":503,"severity":"error","filePath":"lib/routes/bilibili/coin.ts","lineNumber":46,"sourceCode":"    maintainers: ['DIYgod'],\n    handler,\n};\n\nasync function handler(ctx) {\n    const uid = ctx.req.param('uid');\n    const embed = !ctx.req.param('embed');\n\n    const name = await cache.getUsernameFromUID(uid);\n\n    const response = await got({\n        url: `https://api.bilibili.com/x/space/coin/video?vmid=${uid}`,\n        headers: {\n            Referer: `https://space.bilibili.com/${uid}/`,\n        },\n    });\n    const { data, code, message } = response.data;\n    if (code) {\n        throw new Error(message ?? code);\n    }\n\n    return {\n        title: `${name} 的 bilibili 投币视频`,\n        link: `https://space.bilibili.com/${uid}`,\n        description: `${name} 的 bilibili 投币视频`,\n        item: data.map((item) => ({\n            title: item.title,\n            description: utils.renderUGCDescription(embed, item.pic, item.desc, item.aid, undefined, item.bvid),\n            pubDate: parseDate(item.time * 1000),\n            link: item.time > utils.bvidTime && item.bvid ? `https://www.bilibili.com/video/${item.bvid}` : `https://www.bilibili.com/video/av${item.aid}`,\n            author: item.owner.name,\n        })),\n    };\n}\n","sourceCodeStart":28,"sourceCodeEnd":62,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/bilibili/coin.ts#L28-L62","documentation":"Thrown by the bilibili coin route when the bilibili space/coin API returns a non-zero code. The error message prefers the API's own message field and falls back to the numeric code, so callers see whatever bilibili reported (e.g. -101 account not logged in, -352 risk control).","triggerScenarios":"Requesting /bilibili/coin/:uid and the response.data.code is truthy: the user deleted their coins, the cookie is missing/expired, or bilibili's risk control challenged the request.","commonSituations":"No/invalid bilibili cookie configured for the target uid; uid does not exist or hid their coin list; bilibili tightened anti-crawler and returned a code like -352.","solutions":["Read the message/code from the thrown error: -101 means the request needs a logged-in Cookie (set config.bilibili.cookies[uid]); -352 means risk control — retry later or supply a valid cookie.","Confirm the uid exists and has not hidden coin activity.","If the API moved, update the endpoint in the got call."],"exampleFix":"// before\nconst { data, code, message } = response.data;\nif (code) {\n    throw new Error(message ?? code);\n}\n\n// after: distinguish auth vs risk-control so the caller can react\nif (code) {\n    if (code === -101) {\n        throw new ConfigNotFoundError(`Bilibili coin API requires a logged-in cookie for uid ${uid} (code -101).`);\n    }\n    if (code === -352) {\n        throw new CaptchaError(`Bilibili risk control triggered for uid ${uid} (code -352). Retry later.`);\n    }\n    throw new Error(message ?? String(code));\n}","handlingStrategy":"try-catch","validationCode":"const { code, message, data } = response.data ?? {};\nif (code) {\n    // known codes: -101 auth, -352 risk control\n    throw new Error(message ?? String(code));\n}","typeGuard":"function isBilibiliErrorEnvelope(r: any): boolean {\n    return r && typeof r.code === 'number' && r.code !== 0;\n}","tryCatchPattern":"try {\n    const { data, code, message } = response.data;\n    if (code) throw new Error(message ?? code);\n} catch (e) {\n    if (/^-101$/.test(String((e as Error).message))) {\n        // refresh/require cookie for uid\n    }\n    throw e;\n}","preventionTips":["Map known bilibili codes (-101, -352, -404) to specific error types so callers can react.","Set config.bilibili.cookies[uid] for routes that need auth."],"tags":["bilibili","api-error","cookie","anti-bot","propagation"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}