DIYgod/RSSHub · error · Error

Invalid beginDate format. Expected YYYY-MM-DD

Error message

Invalid beginDate format. Expected YYYY-MM-DD

What it means

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>.

Source

Thrown at lib/routes/szse/disclosure/listed-notice.ts:44

export const handler = async (ctx: Context): Promise<Data> => {
    const { category = '' } = ctx.req.param();
    const limit = Number(ctx.req.query('limit') ?? '50');
    const query: string = ctx.req.param('query') ?? '';
    const queries: Record<string, string> = {
        stock: '',
        beginDate: '',
        endDate: '',
    };
    if (query) {
        for (const pair of query.split('&')) {
            const [key, value] = pair.split('=', 2);
            if (key) {
                queries[key] = value;
            }
        }
    }
    if (queries.beginDate && !isValidDate(queries.beginDate)) {
        throw new Error('Invalid beginDate format. Expected YYYY-MM-DD');
    }
    if (queries.endDate) {
        if (!isValidDate(queries.endDate)) {
            throw new Error('Invalid endDate format. Expected YYYY-MM-DD');
        }
    } else if (queries.beginDate) {
        // 如果只提供了开始日期,则将结束日期设置为开始日期
        queries.endDate = queries.beginDate;
    }
    const baseUrl = 'https://www.szse.cn';
    const staticBaseUrl = 'https://disc.static.szse.cn';
    const apiUrl: string = new URL('api/disc/announcement/annList', baseUrl).href;
    const targetUrl: string = new URL(`disclosure/listed/notice${category}`, baseUrl).href;

    const targetResponse = await ofetch(targetUrl);
    const $: CheerioAPI = load(targetResponse);
    const language = $('html').attr('lang') ?? 'zh-CN';
    const response = await ofetch(apiUrl, {

View on GitHub (pinned to bed535e087)

Solutions

  1. Use strict YYYY-MM-DD with leading zeros, e.g. beginDate=2025-02-03.
  2. Drop the beginDate parameter entirely if you do not need a date filter.

Example fix

// before
GET /szse/disclosure/listed/notice/stock=000001&beginDate=2025/2/3
// after
GET /szse/disclosure/listed/notice/stock=000001&beginDate=2025-02-03
Defensive patterns

Strategy: validation

Validate before calling

function isValidDate(dateString: string): boolean {
  if (!/^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/.test(dateString)) {
    return false;
  }
  const [y, m, d] = dateString.split('-').map(Number);
  const date = new Date(y, m - 1, d);
  return date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d;
}

// usage: only call the route when the date is valid
if (beginDate && !isValidDate(beginDate)) {
  // reject client-side
}

Type guard

function isStrictYmd(s: string): s is string {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return false;
  const [y, m, d] = s.split('-').map(Number);
  const date = new Date(y, m - 1, d);
  return date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d;
}

Prevention

When it happens

Trigger: 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).

Common situations: Copying a date from a DD/MM/YYYY locale; omitting leading zeros; using slashes instead of dashes; pasting a date with a time component.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/e86f1d1603ac732a. Report an issue: GitHub.