{"record":{"id":"2f18ad2cb5fbaac9","repo":"DIYgod/RSSHub","slug":"invalid-language-parameter-use-en-or-zh","errorCode":null,"errorMessage":"Invalid language parameter. Use \"en\" or \"zh\".","messagePattern":"Invalid language parameter\\. Use \"en\" or \"zh\"\\.","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"error","filePath":"lib/routes/xjtlu/news.ts","lineNumber":55,"sourceCode":"        zh: { name: '校园与社区', path: 'news_category/topictopic1679' },\n    },\n    about: {\n        en: { name: 'About XJTLU', path: 'news/about-xjtlu' },\n        zh: { name: '要闻聚焦', path: 'news_category/%E8%A6%81%E9%97%BB%E8%81%9A%E7%84%A6' },\n    },\n    stories: {\n        en: { name: 'XJTLU Stories', path: 'news/xjtlu-stories' },\n        zh: { name: '招生专区', path: 'news_category/topictopic4683' },\n    },\n};\n\nconst handler = async (ctx) => {\n    const lang = ctx.req.param('lang') ?? 'en';\n    const category = ctx.req.param('category') ?? 'all';\n\n    // Validate language parameter\n    if (lang !== 'en' && lang !== 'zh') {\n        throw new InvalidParameterError('Invalid language parameter. Use \"en\" or \"zh\".');\n    }\n\n    // Validate category parameter\n    if (!Object.hasOwn(categories, category)) {\n        throw new InvalidParameterError(`Invalid category: ${category}. Please refer to the category table in the documentation.`);\n    }\n\n    // Build the list URL based on category\n    const baseUrl = `https://www.xjtlu.edu.cn/${lang}`;\n    const categoryPath = categories[category][lang].path;\n    const listUrl = `${baseUrl}/${categoryPath}`;\n\n    // Fetch the news list page\n    const response = await ofetch(listUrl);\n    const $ = load(response);\n\n    // Extract article cards from the page\n    const list = $('.card-group-3 .card.up-down-card, .content .card.up-down-card')","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/xjtlu/news.ts#L37-L73","documentation":"InvalidParameterError thrown by the XJTLU news handler when ctx.req.param('lang') is neither 'en' nor 'zh' (the only two language editions the site supports). It guards the URL before it is built, because baseUrl embeds the lang segment directly.","triggerScenarios":"A request to /xjtlu/news/:lang/:category where lang is anything other than 'en' or 'zh' (e.g. 'fr', 'EN ' with whitespace, 'english', or a typo). The check runs before any network call.","commonSituations":"Caller copied an unsupported locale; integrator assumed case-insensitivity (route is case-sensitive, only lowercase 'en'/'zh' pass); mistyped the language segment.","solutions":["Use exactly 'en' or 'zh' for the lang path segment.","If case-insensitivity is desired, normalize: const lang = (ctx.req.param('lang') ?? 'en').toLowerCase(); before the check.","Document the allowed values prominently in the route description."],"exampleFix":"// before\nconst lang = ctx.req.param('lang') ?? 'en';\nif (lang !== 'en' && lang !== 'zh') {\n    throw new InvalidParameterError('Invalid language parameter. Use \"en\" or \"zh\".');\n}\n\n// after — accept case variants while still rejecting unsupported locales\nconst lang = (ctx.req.param('lang') ?? 'en').toLowerCase();\nif (lang !== 'en' && lang !== 'zh') {\n    throw new InvalidParameterError(`Invalid language parameter \"${lang}\". Use \"en\" or \"zh\".`);\n}","handlingStrategy":"validation","validationCode":"const SUPPORTED_LANGS = new Set(['en', 'zh']);\nfunction normalizeLang(raw: string | undefined): 'en' | 'zh' {\n    const lang = (raw ?? 'en').toLowerCase();\n    if (!SUPPORTED_LANGS.has(lang)) {\n        throw new InvalidParameterError(`Invalid language \"${raw}\". Use \"en\" or \"zh\".`);\n    }\n    return lang as 'en' | 'zh';\n}","typeGuard":"function isXjtluLang(value: string): value is 'en' | 'zh' {\n    return value === 'en' || value === 'zh';\n}","tryCatchPattern":null,"preventionTips":["Normalize input case before validating to tolerate 'EN'/'ZH'.","Document the two accepted values in the route description and example.","Use a Set for the allow-list to scale if locales are added."],"tags":["xjtlu","validation","route-param"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}