{"record":{"id":"3020d83367074dda","repo":"DIYgod/RSSHub","slug":"unknown-nav-nav","errorCode":null,"errorMessage":"Unknown nav: ${nav}","messagePattern":"Unknown nav: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/douban/channel/subject.ts","lineNumber":64,"sourceCode":"    const channel_name = channel_info_response.data.title;\n    const data = response.data.modules[nav].payload.subjects;\n    let nav_name: string;\n\n    switch (nav) {\n        case '0':\n            nav_name = '电影';\n            break;\n        case '1':\n            nav_name = '电视剧';\n            break;\n        case '2':\n            nav_name = '书籍';\n            break;\n        case '3':\n            nav_name = '唱片';\n            break;\n        default:\n            throw new Error(`Unknown nav: ${nav}`);\n    }\n\n    return {\n        title: `豆瓣${channel_name}频道-${nav_name}推荐`,\n        link,\n        description: `豆瓣${channel_name}频道书影音下的${nav_name}推荐`,\n\n        item: data.map(({ title, extra, cover_img, url }) => {\n            const rate = extra.rating_group.rating ? `${extra.rating_group.rating.value.toFixed(1)}分` : extra.rating_group.null_rating_reason;\n\n            const description = `标题：${title} <br> 信息：${extra.short_info} <br> 评分：${rate} <br> <img src=\"${cover_img.url}\">`;\n\n            return {\n                title,\n                description,\n                link: url,\n            };\n        }),","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/douban/channel/subject.ts#L46-L82","documentation":"Thrown by the Douban channel subject route when the `nav` path parameter is not one of the four supported values ('0' through '3', mapping to 电影/电视剧/书籍/唱片). The route uses a switch statement with string literal cases; any other value falls through to the default case which throws a plain Error (not InvalidParameterError).","triggerScenarios":"Calling /douban/channel/<id>/subject/<nav> where nav is 4, 5, 'movie', or any non-{0,1,2,3} value; passing a floating-point or padded number like '00' that doesn't match the string literal.","commonSituations":"Developer guesses the nav parameter instead of reading the route description table; a new subject category was added by Douban but not mapped in this route.","solutions":["Use only valid nav values: 0 (电影/Movie), 1 (电视剧/TV), 2 (书籍/Book), 3 (唱片/Music).","Check the route description table for the mapping.","Verify the nav value is a string '0'–'3', not a number or other format."],"exampleFix":"// before\nswitch (nav) {\n    case '0': ... break;\n    // ...\n    default: throw new Error(`Unknown nav: ${nav}`);\n}\n\n// after — use InvalidParameterError with valid options\nconst navMap: Record<string, string> = { '0': '电影', '1': '电视剧', '2': '书籍', '3': '唱片' };\nconst nav_name = navMap[nav];\nif (!nav_name) {\n    throw new InvalidParameterError(`Unknown nav: ${nav}. Valid values: 0, 1, 2, 3`);\n}","handlingStrategy":"validation","validationCode":"const validNavValues = ['0', '1', '2', '3'];\nfunction isValidDoubanNav(nav: string): boolean {\n    return validNavValues.includes(nav);\n}\n\nif (!isValidDoubanNav(nav)) {\n    throw new Error(`Invalid nav '${nav}'. Valid: 0 (Movie), 1 (TV), 2 (Book), 3 (Music)`);\n}","typeGuard":"function isDoubanNav(value: string): value is '0' | '1' | '2' | '3' {\n    return ['0', '1', '2', '3'].includes(value);\n}","tryCatchPattern":"try {\n    const feed = await fetch(`${rsshubUrl}/douban/channel/${id}/subject/${nav}`);\n} catch (e) {\n    if (e.message.includes('Unknown nav')) {\n        console.error(`Nav must be 0-3, got: ${nav}`);\n    }\n    throw e;\n}","preventionTips":["Always validate nav is a string '0' through '3' before using it.","Do not pass integers or padded numbers like '00'.","Check the route description table for the category-to-number mapping."],"tags":["douban","parameter-validation","switch-statement","invalid-parameter"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}