{"record":{"id":"1eee58721888a502","repo":"DIYgod/RSSHub","slug":"error-1eee58","errorCode":null,"errorMessage":"无效的排序类型","messagePattern":"无效的排序类型","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"warning","filePath":"lib/routes/asianfanfics/tag.ts","lineNumber":51,"sourceCode":"    handler,\n};\n\ntype Type = 'L' | 'N' | 'O' | 'C' | 'OS';\n\nconst typeToText = {\n    L: '最近更新',\n    N: '最近发布',\n    O: '最早发布',\n    C: '已完成',\n    OS: '短篇',\n};\n\nasync function handler(ctx) {\n    const tag = ctx.req.param('tag');\n    const type = ctx.req.param('type') as Type;\n\n    if (!type || !['L', 'N', 'O', 'C', 'OS'].includes(type)) {\n        throw new Error('无效的排序类型');\n    }\n    const link = `https://www.asianfanfics.com/browse/tag/${tag}/${type}`;\n\n    const response = await ofetch(link, {\n        headers: {\n            'user-agent': config.trueUA,\n            Referer: 'https://www.asianfanfics.com/',\n        },\n    });\n    const $ = load(response);\n\n    const items: DataItem[] = $('.primary-container .excerpt')\n        .toArray()\n        .filter((element) => {\n            const $element = $(element);\n            return $element.find('.excerpt__title a').length > 0;\n        })\n        .map((element) => {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/asianfanfics/tag.ts#L33-L69","documentation":"Thrown by the asianfanfics tag route when the URL :type parameter is missing or not one of the allowed sort codes L, N, O, C, OS (each mapped to a Chinese label). It is an input-validation guard before the ofetch to asianfanfics.com, so the request never fires for an invalid sort type.","triggerScenarios":"Calling /asianfanfics/tag/:tag/:type with a type value outside {L,N,O,C,OS}, or omitting type entirely so ctx.req.param('type') is undefined.","commonSituations":"User mistypes the sort code; route example copied with a wrong placeholder; upstream adds a new sort option that the route has not whitelisted.","solutions":["Use one of the documented sort codes: L (recently updated), N (recently published), O (earliest published), C (completed), OS (short stories).","If you believe a new code should be supported, add it to both the includes array and the labels map and open a PR."],"exampleFix":"// before\nif (!type || !['L', 'N', 'O', 'C', 'OS'].includes(type)) {\n    throw new Error('无效的排序类型');\n}\n\n// after: derive a typed constant so the allow-list and labels stay in sync\nconst SORT_LABELS = { L: '最近更新', N: '最近发布', O: '最早发布', C: '已完成', OS: '短篇' } as const;\ntype SortType = keyof typeof SORT_LABELS;\nconst VALID_SORTS = new Set(Object.keys(SORT_LABELS));\nif (!VALID_SORTS.has(type)) {\n    throw new InvalidParameterError(`Invalid sort type: ${type}. Allowed: ${[...VALID_SORTS].join(', ')}`);\n}","handlingStrategy":"validation","validationCode":"const VALID_SORTS = new Set(['L', 'N', 'O', 'C', 'OS']);\nconst type = String(ctx.req.param('type') ?? '').toUpperCase();\nif (!VALID_SORTS.has(type)) {\n    throw new InvalidParameterError(`Invalid sort type. Allowed: ${[...VALID_SORTS].join(', ')}`);\n}","typeGuard":"const SORT_LABELS = { L: '最近更新', N: '最近发布', O: '最早发布', C: '已完成', OS: '短篇' } as const;\ntype SortType = keyof typeof SORT_LABELS;\nfunction isSortType(v: string): v is SortType {\n    return Object.prototype.hasOwnProperty.call(SORT_LABELS, v);\n}","tryCatchPattern":null,"preventionTips":["Derive the allow-list and labels from a single object so they cannot drift.","Use InvalidParameterError (not generic Error) so RSSHub returns the correct status."],"tags":["asianfanfics","input-validation","route-parameter","i18n"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}