{"record":{"id":"2473317e35f4d2c8","repo":"DIYgod/RSSHub","slug":"unknown-type-contentitem-type","errorCode":null,"errorMessage":"Unknown type: ${contentItem.type}","messagePattern":"Unknown type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/zhihu/activities.ts","lineNumber":120,"sourceCode":"                            case 'link':\n                                link = `<p><a href=\"${contentItem.url}\" target=\"_blank\">${contentItem.title}</a></p>`;\n\n                                break;\n\n                            case 'video':\n                                link = `<p><video\n                                controls=\"controls\"\n                                width=\"${contentItem.playlist[1].width}\"\n                                height=\"${contentItem.playlist[1].height}\"\n                                src=\"${contentItem.playlist[1].url}\"></video></p>`;\n\n                                break;\n                            case 'link_card':\n                                link = `<p><a href=\"${contentItem.url.split('?', 1)[0]}\" target=\"_blank\"></a></p>`;\n                                break;\n\n                            default:\n                                throw new Error(`Unknown type: ${contentItem.type}`);\n                        }\n                    }\n                    description = `${text}${link}${images.join('')}`;\n                    url = `https://www.zhihu.com/pin/${detail.id}`;\n                    break;\n                case 'question':\n                    title = detail.title;\n                    author = detail.author.name;\n                    description = processImage(detail.detail);\n                    url = `https://www.zhihu.com/question/${detail.id}`;\n                    break;\n                case 'collection':\n                    title = detail.title;\n                    url = `https://www.zhihu.com/collection/${detail.id}`;\n                    break;\n                case 'column':\n                    title = detail.title;\n                    description = `<p>${detail.intro}</p><p><img src=\"${detail.image_url}\"/></p>`;","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/zhihu/activities.ts#L102-L138","documentation":"Thrown from the inner content-item switch while rendering a Zhihu \"pin\" (想法/short post) in the activities feed. The switch handles content item types `text`, `image`, `link`, `video`, and `link_card`; any other `contentItem.type` hits the `default` and throws, echoing the unknown type so the unhandled payload shape is visible.","triggerScenarios":"A Zhihu pin contains a content block of a type the route has not encoded — e.g. Zhihu adds a new embed type (audio, poll, article-embed, repost) to the pin content array, or renames an existing type string.","commonSituations":"Zhihu rolls out a new pin content feature; the API starts returning a previously-unseen type for certain pins; a reposted/quoted pin carries a nested structure with a different type tag. Because the throw is uncaught it fails the entire activity feed for that user.","solutions":["Capture the `contentItem.type` from the error and add a `case` that renders it (commonly a link, an `<img>`, or an `<iframe>` depending on the payload fields).","If the new type's rendering is unknown, make `default` skip the item (continue/break with empty HTML) instead of throwing, so the rest of the pin still renders.","Check the Zhihu web/app pin UI for the new block to infer the right HTML mapping."],"exampleFix":"// before\ndefault:\n    throw new Error(`Unknown type: ${contentItem.type}`);\n// after — graceful skip for unknown pin content types\ndefault:\n    break;","handlingStrategy":"type-guard","validationCode":"const HANDLED_PIN_CONTENT_TYPES = new Set(['text', 'image', 'link', 'video', 'link_card']);\nfunction filterPinContent(content) {\n    return content.filter((item) => HANDLED_PIN_CONTENT_TYPES.has(item.type));\n}","typeGuard":"type HandledPinType = 'text' | 'image' | 'link' | 'video' | 'link_card';\nconst HANDLED: Set<HandledPinType> = new Set(['text','image','link','video','link_card']);\nfunction isHandledPinType(item: { type: string }): item is { type: HandledPinType } {\n    return HANDLED.has(item.type as HandledPinType);\n}","tryCatchPattern":"// Render only known content types; skip the rest instead of throwing\nfor (const contentItem of detail.content) {\n    if (!isHandledPinType(contentItem)) continue;\n    // ... existing switch\n}","preventionTips":["Filter the pin content array to known types before the switch so unknown blocks are skipped, not fatal.","Log unknown content types at warn level to detect Zhihu API additions.","Add new types as explicit cases once their payload shape is understood."],"tags":["zhihu","content-parsing","switch-enum","activities","api-change"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}