{"record":{"id":"cc0479c0c0d0b6eb","repo":"DIYgod/RSSHub","slug":"failed-to-fetch-announcements-error-code-res","errorCode":null,"errorMessage":"Failed to fetch announcements, error code: ' + result?.code","messagePattern":"Failed to fetch announcements, error code: ' \\+ result\\?\\.code","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/bitget/announcement.ts","lineNumber":76,"sourceCode":"        case 'all':\n            reqBody.stationLetterType = '0';\n            reqBody.excludeStationLetterType = '00';\n            break;\n\n        default:\n            throw new Error('Invalid type');\n    }\n\n    const response = (await cache.tryGet(\n        `bitget:announcement:${type}:${pageSize}:${lang}`,\n        async () => {\n            const result = await ofetch<BitgetResponse>(announcementApiUrl, {\n                method: 'POST',\n                body: reqBody,\n                headers,\n            });\n            if (result?.code !== '200') {\n                throw new Error('Failed to fetch announcements, error code: ' + result?.code);\n            }\n            return result;\n        },\n        config.cache.routeExpire,\n        false\n    )) as BitgetResponse;\n\n    if (!response) {\n        throw new Error('Failed to fetch announcements');\n    }\n    const items = response.data.items;\n    const data = await Promise.all(\n        items.map(\n            (item) =>\n                cache.tryGet(`bitget:announcement:${item.id}:${pageSize}:${lang}`, async () => {\n                    // 从 unix 时间戳转换为日期\n                    const date = parseDate(Number(item.sendTime));\n                    const dataItem: DataItem = {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/bitget/announcement.ts#L58-L94","documentation":"Generic Error thrown inside the cache.tryGet fetcher closure when Bitget's /v1/msg/push/stationLetterNew POST returns a body whose `code` field is not '200'. Because the throw happens inside the async getter, cache.tryGet (called with cacheErrorFlag=false) will NOT cache the failure and the error propagates to the request.","triggerScenarios":"The POST to the Bitget announcement API succeeds at the HTTP level but the JSON envelope reports a non-success code (e.g. rate-limit, maintenance, invalid languageType, or a changed contract). result?.code !== '200' triggers the throw.","commonSituations":"Bitget rate-limiting the IP; sending a lang that maps to an unsupported languageType; Bitget changing their response envelope; transient backend errors on Bitget's side.","solutions":["Retry shortly — transient Bitget backend errors usually clear; note cache.tryGet already avoids caching the bad result.","Verify the lang parameter is supported (default zh-CN) and languageType/locale headers are well-formed.","If persistent, manually call the Bitget API to read the exact non-200 code and message, then update the route.","Confirm the announcementApiUrl endpoint is still valid (Bitget may have versioned it)."],"exampleFix":"// before\nif (result?.code !== '200') {\n    throw new Error('Failed to fetch announcements, error code: ' + result?.code);\n}\n// after (include the API message for diagnosis)\nif (result?.code !== '200') {\n    throw new Error(`Failed to fetch announcements, code: ${result?.code}, msg: ${result?.msg ?? result?.message}`);\n}","handlingStrategy":"retry","validationCode":"const result = await ofetch<BitgetResponse>(announcementApiUrl, { method:'POST', body: reqBody, headers });\nif (!result || result.code !== '200') {\n    throw new Error('Failed to fetch announcements, error code: ' + result?.code);\n}","typeGuard":"const isBitgetSuccess = (r: BitgetResponse | undefined): boolean =>\n    !!r && r.code === '200' && Array.isArray(r.data?.items);","tryCatchPattern":"// cache.tryGet is called with cacheErrorFlag=false, so failures are not cached.\n// Wrap to retry transient non-200s a bounded number of times:\nlet lastErr;\nfor (let i = 0; i < 3; i++) {\n    try { return await fetchOnce(); }\n    catch (e) { lastErr = e; await delay(500 * (i + 1)); }\n}\nthrow lastErr;","preventionTips":["Keep cacheErrorFlag=false so transient Bitget errors are not cached as stale failures.","Verify the lang/languageType mapping before deploying a new locale.","Monitor the exact non-200 code to distinguish rate-limit from contract change."],"tags":["bitget","api-error","cache","response-shape"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}