{"record":{"id":"fac96c4d90a29429","repo":"DIYgod/RSSHub","slug":"invalid-category-fac96c","errorCode":null,"errorMessage":"Invalid category","messagePattern":"Invalid category","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"warning","filePath":"lib/routes/huanqiu/index.ts","lineNumber":51,"sourceCode":"    },\n    radar: [\n        {\n            source: ['huanqiu.com/'],\n        },\n    ],\n    name: '分类',\n    maintainers: ['yuxinliu-alex'],\n    handler,\n    url: 'huanqiu.com/',\n    description: `| 国内新闻 | 国际新闻 | 军事 | 台海   | 评论    |\n| -------- | -------- | ---- | ------ | ------- |\n| china    | world    | mil  | taiwai | opinion |`,\n};\n\nasync function handler(ctx) {\n    const category = ctx.req.param('category') ?? 'china';\n    if (!isValidHost(category)) {\n        throw new InvalidParameterError('Invalid category');\n    }\n\n    const host = `https://${category}.huanqiu.com`;\n\n    const resp = await got({\n        method: 'get',\n        url: `${host}/api/channel_pc`,\n    });\n\n    const name = getKeysRecursive(resp.data.children, 'children', 'domain_name', [])[0];\n\n    const nodes = getKeysRecursive(resp.data.children, 'children', 'node', [])\n        .map((x) => `\"${x}\"`)\n        .join(',');\n    const req = await got({\n        method: 'get',\n        url: `${host}/api/list?node=${nodes}&offset=0&limit=${ctx.req.query('limit') ?? 20}`,\n    });","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/huanqiu/index.ts#L33-L69","documentation":"Thrown by the Huanqiu (环球网) news route when `isValidHost(category)` returns false for the `:category` path parameter. The handler constructs `https://${category}.huanqiu.com`, so `category` must be a valid DNS subdomain. The `isValidHost` utility does a DNS lookup to confirm `<category>.huanqiu.com` resolves. Documented values are `china`, `world`, `mil`, `taiwai`, `opinion`.","triggerScenarios":"Requesting `/huanqiu/news/<category>` where `<category>.huanqiu.com` does not resolve in DNS, or where the category string contains invalid hostname characters. Note: the default is `china`, so omitting the parameter is safe.","commonSituations":"Typo in the category slug (e.g. `taiwai` is easy to misspell as `taiwan`), using a category subdomain that huanqiu does not operate, or DNS resolution failure in the deployment environment.","solutions":["Use one of the documented categories: `china`, `world`, `mil`, `taiwai`, `opinion`.","Verify `<category>.huanqiu.com` resolves via `dig` or `nslookup`.","If deploying behind a restricted DNS, ensure the deployment environment can resolve huanqiu.com subdomains."],"exampleFix":"// before (broken)\n// GET /huanqiu/news/taiwan\n\n// after (correct — note the unusual spelling)\n// GET /huanqiu/news/taiwai","handlingStrategy":"validation","validationCode":"const VALID_CATEGORIES = ['china', 'world', 'mil', 'taiwai', 'opinion'];\nfunction isValidCategory(category: string): boolean {\n    return VALID_CATEGORIES.includes(category);\n}\n// The route uses isValidHost(category) which does DNS resolution.\n// Pre-checking against known values is faster and avoids DNS lookups for typos.","typeGuard":"function isKnownHuanqiuCategory(category: string): category is 'china' | 'world' | 'mil' | 'taiwai' | 'opinion' {\n    return ['china', 'world', 'mil', 'taiwai', 'opinion'].includes(category);\n}","tryCatchPattern":null,"preventionTips":["Note the unusual spelling `taiwai` (not `taiwan`) — document this prominently.","Pre-validate against the known set before DNS resolution to fail faster on typos.","Omit the category parameter to default to `china`."],"tags":["parameter-validation","dns","rsshub","traditional-media"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}