{"record":{"id":"e86f1d1603ac732a","repo":"DIYgod/RSSHub","slug":"invalid-begindate-format-expected-yyyy-mm-dd","errorCode":null,"errorMessage":"Invalid beginDate format. Expected YYYY-MM-DD","messagePattern":"Invalid beginDate format\\. Expected YYYY-MM-DD","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/szse/disclosure/listed-notice.ts","lineNumber":44,"sourceCode":"export const handler = async (ctx: Context): Promise<Data> => {\n    const { category = '' } = ctx.req.param();\n    const limit = Number(ctx.req.query('limit') ?? '50');\n    const query: string = ctx.req.param('query') ?? '';\n    const queries: Record<string, string> = {\n        stock: '',\n        beginDate: '',\n        endDate: '',\n    };\n    if (query) {\n        for (const pair of query.split('&')) {\n            const [key, value] = pair.split('=', 2);\n            if (key) {\n                queries[key] = value;\n            }\n        }\n    }\n    if (queries.beginDate && !isValidDate(queries.beginDate)) {\n        throw new Error('Invalid beginDate format. Expected YYYY-MM-DD');\n    }\n    if (queries.endDate) {\n        if (!isValidDate(queries.endDate)) {\n            throw new Error('Invalid endDate format. Expected YYYY-MM-DD');\n        }\n    } else if (queries.beginDate) {\n        // 如果只提供了开始日期，则将结束日期设置为开始日期\n        queries.endDate = queries.beginDate;\n    }\n    const baseUrl = 'https://www.szse.cn';\n    const staticBaseUrl = 'https://disc.static.szse.cn';\n    const apiUrl: string = new URL('api/disc/announcement/annList', baseUrl).href;\n    const targetUrl: string = new URL(`disclosure/listed/notice${category}`, baseUrl).href;\n\n    const targetResponse = await ofetch(targetUrl);\n    const $: CheerioAPI = load(targetResponse);\n    const language = $('html').attr('lang') ?? 'zh-CN';\n    const response = await ofetch(apiUrl, {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/szse/disclosure/listed-notice.ts#L26-L62","documentation":"Thrown by szse/disclosure/listed-notice.ts:44 via `throw new Error(...)` (note: NOT an InvalidParameterError) when the beginDate parsed from the :query path param fails isValidDate. isValidDate (line 11) enforces strict YYYY-MM-DD via regex AND a real-calendar check (so 2025-02-30 fails). The query string is split on '&' then '='. The check is guarded by `if (queries.beginDate && ...)`, so an empty/absent beginDate is allowed. Reached via /szse/disclosure/listed/notice/<query>.","triggerScenarios":"beginDate=2025-13-01 (bad month), beginDate=2025-02-30 (non-existent day), beginDate=2025/02/03 (slashes), beginDate=2025-2-3 (missing leading zeros), beginDate=20250203 (no dashes).","commonSituations":"Copying a date from a DD/MM/YYYY locale; omitting leading zeros; using slashes instead of dashes; pasting a date with a time component.","solutions":["Use strict YYYY-MM-DD with leading zeros, e.g. beginDate=2025-02-03.","Drop the beginDate parameter entirely if you do not need a date filter."],"exampleFix":"// before\nGET /szse/disclosure/listed/notice/stock=000001&beginDate=2025/2/3\n// after\nGET /szse/disclosure/listed/notice/stock=000001&beginDate=2025-02-03","handlingStrategy":"validation","validationCode":"function isValidDate(dateString: string): boolean {\n  if (!/^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])$/.test(dateString)) {\n    return false;\n  }\n  const [y, m, d] = dateString.split('-').map(Number);\n  const date = new Date(y, m - 1, d);\n  return date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d;\n}\n\n// usage: only call the route when the date is valid\nif (beginDate && !isValidDate(beginDate)) {\n  // reject client-side\n}","typeGuard":"function isStrictYmd(s: string): s is string {\n  if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(s)) return false;\n  const [y, m, d] = s.split('-').map(Number);\n  const date = new Date(y, m - 1, d);\n  return date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d;\n}","tryCatchPattern":null,"preventionTips":["Always use strict YYYY-MM-DD with leading zeros (e.g. 2025-02-03).","Omit beginDate entirely if no date filter is needed.","Avoid locale-specific formats (DD/MM/YYYY) and slashes."],"tags":["invalid-parameter","date-validation","finance","szse","wrong-error-type"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}