{"record":{"id":"d50d21b0d618e592","repo":"DIYgod/RSSHub","slug":"unknown-action-key-item-key","errorCode":null,"errorMessage":"Unknown action key: ${item.key}","messagePattern":"Unknown action key: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"warning","filePath":"lib/routes/sspai/activity.ts","lineNumber":99,"sourceCode":"                    item_url = `https://sspai.com/post/${content_data.id}`;\n                    break;\n                case 'comment_article':\n                    item_title = `${item.author.nickname}${item.action}：${content_data.article_title}`;\n                    item_desc = content_data.comment;\n                    item_url = `https://sspai.com/post/${content_data.article_id}`;\n                    break;\n                case 'release_article':\n                    item_title = `${item.author.nickname}${item.action}：${content_data.title}`;\n                    item_desc = content_data.summary;\n                    item_url = `https://sspai.com/post/${content_data.id}`;\n                    break;\n                case 'chosen_comment':\n                    item_title = `${item.author.nickname}在文章「${content_data.article_title}」下的${item.action}`;\n                    item_desc = content_data.comment;\n                    item_url = content_data.comment;\n                    break;\n                default:\n                    throw new Error(`Unknown action key: ${item.key}`);\n            }\n\n            return {\n                title: item_title,\n                description: item_desc,\n                link: item_url,\n                pubDate: parseDate(item.created_at * 1000),\n            };\n        }),\n    };\n}\n","sourceCodeStart":81,"sourceCodeEnd":111,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/sspai/activity.ts#L81-L111","documentation":"Thrown as a plain Error from the default case of a switch statement that handles sspai (少数派) user activity items. The switch maps known item.key values (follow_user, like_article, comment_article, release_article, chosen_comment) to feed entry shapes. If the sspai activity API returns an item with an unrecognized key value, the default branch throws with the unknown key interpolated in the message. This is a forward-compatibility guard: it surfaces new API action types that the route has not been updated to handle.","triggerScenarios":"The sspai API (/api/v1/information/user/activity/page/get) returns an activity item whose `key` field is a value not in the switch (e.g. 'like_comment', 'follow_collection', or any newly introduced activity type). This causes the entire feed generation to fail with this error, losing all items in the batch.","commonSituations":"sspai adds a new activity type to their platform (e.g. a new 'bookmark' or 'share' action) and the API starts returning it; the activity list for a specific user happens to contain only items of the new type; or sspai renames an existing action key.","solutions":["Inspect the sspai API response to identify the new item.key value: fetch the activity endpoint with the user's slug and examine the data array.","Add a new case branch in the switch statement for the unknown key, mapping it to appropriate title/description/link fields.","As a quick workaround to prevent total feed failure, change the default case from `throw` to `return null` (or skip) so other items still render — but this masks the problem and should be fixed properly.","File an issue or PR to add support for the new activity type."],"exampleFix":"// before\ndefault:\n    throw new Error(`Unknown action key: ${item.key}`);\n\n// after (graceful skip)\ndefault:\n    return null;\n\n// after (proper handling of new type)\ncase 'like_comment':\n    item_title = `${item.author.nickname}${item.action}：${content_data.comment}`;\n    item_desc = content_data.comment;\n    item_url = `https://sspai.com/post/${content_data.article_id}`;\n    break;","handlingStrategy":"fallback","validationCode":"const KNOWN_KEYS = new Set(['follow_user', 'like_article', 'comment_article', 'release_article', 'chosen_comment']);\n// Before mapping, filter out unknown keys or handle gracefully\ndata.filter((item) => KNOWN_KEYS.has(item.key)).map(/* ... */)","typeGuard":"const KNOWN_ACTION_KEYS = ['follow_user', 'like_article', 'comment_article', 'release_article', 'chosen_comment'] as const;\ntype ActionKey = typeof KNOWN_ACTION_KEYS[number];\nfunction isKnownActionKey(key: string): key is ActionKey {\n    return (KNOWN_ACTION_KEYS as readonly string[]).includes(key);\n}","tryCatchPattern":"item: data\n    .filter((item) => isKnownActionKey(item.key))\n    .map((item) => {\n        // switch on item.key — TS now narrows to ActionKey\n        switch (item.key) {\n            // ...\n        }\n    }),","preventionTips":["Use a typed union for known action keys so TypeScript exhaustiveness checking flags missing cases at compile time.","Replace `throw` in the default case with `return null` and filter nulls, so one unknown activity type does not break the entire feed.","Log unknown keys to logger.warn so maintainers are alerted to new activity types without breaking user-facing feeds.","Add unit tests that include mock data with all known action keys plus an unknown one to verify graceful degradation."],"tags":["api","upstream","forward-compat","switch-default","sspai"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}