{"record":{"id":"622e5e876e07a0f3","repo":"DIYgod/RSSHub","slug":"message-622e5e","errorCode":null,"errorMessage":"message","messagePattern":"message","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/sicau/jk.ts","lineNumber":121,"sourceCode":"                id: each.id,\n                guid: each.id,\n                title: each.title,\n                image: each.logo,\n            }));\n\n        const items = await Promise.all(\n            list.map((item) =>\n                cache.tryGet(String(item.id), async () => {\n                    const { code, message, content } = await $post(`/getActDetail?actId=${item.id}`);\n                    if (code === '0') {\n                        item.author = content.groupName;\n                        item.pubDate = timezone(parseDate(content.startDate, 'YYYY-MM-DD HH:mm:ss'), 8);\n                        item.category = [content.typeName, content.levelName];\n                        item.description = `<img src=\"${item.image}\" alt=\"${item.title}\" /><p style='white-space: pre-wrap'>${content.description}</p>`;\n\n                        return item;\n                    }\n                    throw new Error(message);\n                })\n            )\n        );\n\n        return {\n            title: '二课活动 - 四川农业大学',\n            link: 'https://jk.sicau.edu.cn/act/actInfo/v1.0.0/getUserSchoolActList',\n            language: 'zh-CN',\n            item: items as DataItem[],\n        };\n    },\n};\n\nconst typeDict = {\n    '0': '',\n    '1': '17a3b11f2d254518b13406ccd18a85b5',\n    '2': '000392a845ff47d09978c6ddd6dda2d4',\n    '3': '9ead58d01d3d424ea70b194910893660',","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/sicau/jk.ts#L103-L139","documentation":"Inside the SICAU route, each activity id is fetched in detail via `/getActDetail` and cached with `cache.tryGet`. If the response `code` is anything other than `'0'`, the cached function throws the upstream `message`. Because this happens inside `Promise.all`, a single failing detail call rejects the entire items array, aborting the feed build.","triggerScenarios":"One activity id in the list returns a non-zero code from the detail endpoint (activity deleted between list and detail fetch, restricted, or backend error). Cached failures will keep returning the same error until the cache entry expires.","commonSituations":"Activity removed after appearing in the list; transient backend 5xx returned as `code !== '0'`; cached bad response keeping the error sticky.","solutions":["Clear the cache entry for the failing id (or wait for TTL) — `cache.tryGet(String(item.id), ...)` will then re-fetch.","Retry the route; transient backend issues often clear on the next list refresh.","Patch the handler to skip items whose detail returns `code !== '0'` instead of throwing, so one bad activity does not break the feed."],"exampleFix":"// before\nif (code === '0') {\n    // ... populate item\n    return item;\n}\nthrow new Error(message);\n\n// after\nif (code === '0') {\n    // ... populate item\n    return item;\n}\nreturn null;\n// then filter nulls before returning items","handlingStrategy":"try-catch","validationCode":"const detail = await $post(`/getActDetail?actId=${item.id}`);\nif (detail.code !== '0') {\n    return null; // skip and filter later\n}","typeGuard":"const isDetailOk = (r: unknown): boolean => (r as any)?.code === '0';","tryCatchPattern":"try {\n    item = await cache.tryGet(String(item.id), async () => { /* ... */ throw new Error(message); });\n} catch (e) {\n    if (e instanceof Error) item = null; // tolerate\n    else throw e;\n}","preventionTips":["Filter nulls after Promise.all so one bad detail does not reject the whole feed.","Wrap cache.tryGet in try/catch to avoid caching a thrown error.","Use Promise.allSettled instead of Promise.all for resilience."],"tags":["upstream-api","cache-staleness","university"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}