{"record":{"id":"1ddd33bd73ae923f","repo":"jackwener/OpenCLI","slug":"rawinput-does-not-look-like-a-dongchedi-serie","errorCode":null,"errorMessage":"'${rawInput}' does not look like a dongchedi series id (a number, or a /auto/series/<id> URL)","messagePattern":"'(.+?)' does not look like a dongchedi series id \\(a number, or a /auto/series/<id> URL\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/dongchedi/utils.js","lineNumber":154,"sourceCode":"}\n\n/** Rescale a Dongchedi x100 score int (422) to a /5 float (4.22). */\nexport function parseScore(raw) {\n    const n = Number(raw);\n    if (!Number.isFinite(n) || n <= 0) return null;\n    return Number((n / 100).toFixed(2));\n}\n\n/**\n * Normalize a series id argument: a bare number, or a\n * `https://www.dongchedi.com/auto/series/<id>` URL.\n */\nexport function normalizeSeriesId(rawInput) {\n    const raw = String(rawInput || '').trim();\n    if (!raw) throw new ArgumentError('series_id must be a non-empty value');\n    const m = raw.match(/series\\/(\\d+)/) || raw.match(/^(\\d+)$/);\n    if (!m) {\n        throw new ArgumentError(\n            `'${rawInput}' does not look like a dongchedi series id (a number, or a /auto/series/<id> URL)`,\n        );\n    }\n    return m[1];\n}\n\n/** Validate an integer limit in [1, max]. */\nexport function requireLimit(value, def, max) {\n    const raw = value == null || value === '' ? def : value;\n    const n = typeof raw === 'number' ? raw : Number(String(raw).trim());\n    if (!Number.isInteger(n) || n < 1 || n > max) {\n        throw new ArgumentError(`limit must be an integer between 1 and ${max}`);\n    }\n    return n;\n}\n\n/** Collapse whitespace and trim; returns '' for nullish. */\nexport function clean(s) {","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dongchedi/utils.js#L136-L172","documentation":"normalizeSeriesId accepts only a bare digit string or a dongchedi /auto/series/<id> URL. It throws ArgumentError when the input is non-empty but matches neither pattern, so the library cannot extract a numeric series id from it.","triggerScenarios":"Passing values like 'series/4694' (no domain prefix), a full dongchedi URL with a different path shape (e.g. /auto/spec/<id>), a model name string, an id with letters or whitespace inside, or a decimal like '4694.5'.","commonSituations":"Copying a partial URL fragment instead of the full URL; pasting a car model name instead of the numeric id; confusion with spec (车型) ids from /auto/spec/ pages which use a different id space.","solutions":["Pass the full URL form: https://www.dongchedi.com/auto/series/4694","Or pass just the numeric id string, e.g. seriesId('4694')","Open the dongchedi series page in a browser and copy the number after /auto/series/ — note spec ids (/auto/spec/) are different and will not match"],"exampleFix":"// before\nawait seriesId('https://www.dongchedi.com/auto/spec/7005');\n// after\nawait seriesId('https://www.dongchedi.com/auto/series/4694');","handlingStrategy":"validation","validationCode":"const raw = String(input ?? '').trim();\nconst m = raw.match(/series\\/(\\d+)/) || raw.match(/^(\\d+)$/);\nif (!m) throw new Error(`'${input}' is not a dongchedi series id (number or /auto/series/<id> URL)`);","typeGuard":"function looksLikeSeriesId(v) { const s = String(v ?? '').trim(); return /^\\d+$/.test(s) || /series\\/\\d+/.test(s); }","tryCatchPattern":"try { await seriesId(input); } catch (e) { if (e.name === 'ArgumentError') { console.error('Expected a number or https://www.dongchedi.com/auto/series/<id>'); } else throw e; }","preventionTips":["Store the numeric id, not the whole URL, in config/scripts","Extract ids with a regex when accepting pasted URLs","Do not confuse /auto/spec/ ids with /auto/series/ ids"],"tags":["argument-error","input-validation","regex-match","dongchedi"],"backgroundTag":"invalid-argument-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}