{"record":{"id":"f668304888ea20e0","repo":"DIYgod/RSSHub","slug":"invalid-category-category-please-refer-to-the","errorCode":null,"errorMessage":"Invalid category: ${category}. Please refer to the category table in the documentation.","messagePattern":"Invalid category: (.+?)\\. Please refer to the category table in the documentation\\.","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":503,"severity":"error","filePath":"lib/routes/xjtlu/news.ts","lineNumber":60,"sourceCode":"    },\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')\n        .toArray()\n        .map((item) => {\n            const $item = $(item);\n            const link = $item.find('.a-links-block').attr('href');\n            const title = $item.find('.card-title').text().trim();","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/xjtlu/news.ts#L42-L78","documentation":"InvalidParameterError thrown by the XJTLU news handler when ctx.req.param('category') is not a key of the categories map (all, anniversary, technology, business, environment, humanities, community, about, stories). Object.hasOwn rejects unknown categories before the URL is constructed, preventing 404s on xjtlu.edu.cn.","triggerScenarios":"A request to /xjtlu/news/:lang/:category with a category string that is not one of the nine defined keys, e.g. /xjtlu/news/en/research or a typo like 'tech' instead of 'technology'.","commonSituations":"Caller guessed a category name not in the route docs; XJTLU restructured news sections and a previously valid key was removed; user passed an empty-but-defined category that is not 'all'.","solutions":["Use one of the documented category keys (all, anniversary, technology, business, environment, humanities, community, about, stories).","Omit the category segment to fall back to the 'all' default.","If the site added a section, add it to the categories map and rebuild."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const CATEGORY_KEYS = new Set(Object.keys(categories));\nfunction resolveCategory(raw: string | undefined): keyof typeof categories {\n    const category = raw ?? 'all';\n    if (!CATEGORY_KEYS.has(category)) {\n        throw new InvalidParameterError(`Invalid category \"${category}\". Valid: ${[...CATEGORY_KEYS].join(', ')}`);\n    }\n    return category as keyof typeof categories;\n}","typeGuard":"function isXjtluCategory(value: string): value is keyof typeof categories {\n    return Object.hasOwn(categories, value);\n}","tryCatchPattern":null,"preventionTips":["Derive the allow-list from the categories object itself so it stays in sync.","Default to 'all' when the segment is omitted.","Re-check the categories map if XJTLU restructures its news sections."],"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"}