{"record":{"id":"c95b6b201f64e050","repo":"DIYgod/RSSHub","slug":"unhandled-card-on-link-name","errorCode":null,"errorMessage":"Unhandled card on ${link}: ${name}","messagePattern":"Unhandled card on (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/yuque/utils.ts","lineNumber":75,"sourceCode":"                throw new Error(`Unhandled thirdparty on ${link}: ${elem.attr('alias')}`);\n            }\n            break;\n        case 'yuque':\n            if (value.mode === 'card') {\n                html = `<a href='${value.src}'>${value.detail.title}</a>`;\n            } else if (value.mode === 'embed') {\n                html = `<iframe src=\"${value.url}\" width=\"100%\" height=\"518\"></iframe>`;\n            } else {\n                throw new Error(`Unhandled mode on ${link}: ${value.mode}`);\n            }\n            break;\n        case 'video':\n            // fake video src\n            html = `<video src='${value.videoId}'></video>`;\n            break;\n\n        default:\n            throw new Error(`Unhandled card on ${link}: ${name}`);\n    }\n    elem.replaceWith(html);\n};\n\nexport { card2Html };\n","sourceCodeStart":57,"sourceCodeEnd":81,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/yuque/utils.ts#L57-L81","documentation":"The `default` arm of the `name` switch in `card2Html`. It fires when a Yuque `<card>` element has a `name` attribute not covered by any defined case (board, emoji, image, thirdparty, yuque, video, etc.). The message reports the document link and the unknown card name.","triggerScenarios":"Yuque introduces a brand-new block/card type (e.g. a callout, a new diagram kind, an attachment variant) so the serialized card carries a `name` value absent from the switch.","commonSituations":"Yuque releases a new editor feature; an existing card is renamed; the document was authored with a newer Yuque editor than the route supports. The throw aborts rendering of that document's whole body.","solutions":["Take the `name` from the error message and add a `case` that maps it to the right HTML (often an `<img src='${value.src}'>` or `<a href='${value.src}'>` depending on the payload).","If you cannot determine the right HTML yet, make the `default` arm non-fatal — replace the card with an empty string or a placeholder link so the rest of the document still renders.","Add the new card name to the known list and open an upstream issue to track full support."],"exampleFix":"// before\ndefault:\n    throw new Error(`Unhandled card on ${link}: ${name}`);\n// after (graceful fallback + new case)\ncase 'callout':\n    html = `<blockquote>${value.text ?? ''}</blockquote>`;\n    break;\ndefault:\n    html = '';\n    elem.remove();\n    break;","handlingStrategy":"try-catch","validationCode":"const knownCardNames = new Set([\n    'board','emoji','flowchart2','image','math','mindmap','puml',\n    'bookmarkInline','bookmarklink','yuqueinline','checkbox','codeblock',\n    'diagram','file','localdoc','hr','label','mention','table',\n    'thirdparty','youku','yuque','video',\n]);\nfunction isKnownCard(name) {\n    return knownCardNames.has(name);\n}","typeGuard":"function isKnownCardName(name: string | undefined): boolean {\n    return typeof name === 'string' && KNOWN_CARD_NAMES.has(name);\n}","tryCatchPattern":"try {\n    card2Html(elem, link);\n} catch (e) {\n    logger.warn(`Skipping unhandled yuque card '${elem.attr('name')}' on ${link}`);\n    elem.remove();\n}","preventionTips":["Never let card2Html throw propagate out of the per-element loop — isolate each card's failure.","Keep a fixture set of Yuque documents exercising every known card name.","Log unknown card names at warn level so schema drift is visible without breaking feeds."],"tags":["yuque","content-parsing","switch-enum","default-case"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}