{"record":{"id":"032e38b1bc7fe29c","repo":"jackwener/OpenCLI","slug":"label-year","errorCode":null,"errorMessage":"${label} 非法：${year}，应为正整数","messagePattern":"(.+?) 非法：(.+?)，应为正整数","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/mubu/notes.js","lineNumber":18,"sourceCode":"import { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError } from '@jackwener/opencli/errors';\nimport { mubuPost, nodesToMarkdown, nodesToText, htmlToText } from './utils.js';\n\n// ── 日期工具 ──────────────────────────────────────────────\n\nfunction localToday() {\n  const d = new Date();\n  return { year: d.getFullYear(), month: d.getMonth() + 1, day: d.getDate() };\n}\n\nfunction lastDayOfMonth(year, month) {\n  return new Date(year, month, 0).getDate();\n}\n\nfunction validateYear(year, label = '年份') {\n  if (!Number.isInteger(year) || year < 1) {\n    throw new ArgumentError(`${label} 非法：${year}，应为正整数`);\n  }\n}\n\nfunction validateMonth(month) {\n  if (!Number.isInteger(month) || month < 1 || month > 12) {\n    throw new ArgumentError(`月份非法：${month}，应为 1-12`);\n  }\n}\n\nfunction validateDay(year, month, day) {\n  const maxDay = lastDayOfMonth(year, month);\n  if (!Number.isInteger(day) || day < 1 || day > maxDay) {\n    throw new ArgumentError(`日期非法：${year}-${month}-${day}（${year} 年 ${month} 月共 ${maxDay} 天）`);\n  }\n}\n\nfunction parseDate(s) {\n  const parts = s.split('-').map(Number);","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/mubu/notes.js#L1-L36","documentation":"validateYear in clis/mubu/notes.js guards year inputs used by date parsing helpers (parseDate, parseMonth, resolveRange). It throws ArgumentError ('<label> 非法：<year>，应为正整数' — '<label> is invalid: <year>, expected a positive integer') when the value is not an integer or is less than 1. The label names which field failed (e.g. 年份).","triggerScenarios":"Calling parseDate, parseMonth, or resolveRange with a year that is non-integer (e.g. 2026.5), zero, negative, NaN, or an uncoerced numeric string ('2026') — any value failing Number.isInteger(year) || year < 1.","commonSituations":"Passing a user-supplied --year string straight from argv without Number conversion; an empty flag producing NaN/undefined; 2-digit years like '26'; negative years from mis-parsed date arithmetic in range queries.","solutions":["Convert the input first: Number.parseInt(value, 10) and verify with Number.isInteger.","Pass a full 4-digit positive integer year (e.g. 2026).","Default empty/undefined flag values explicitly instead of letting them become NaN.","If the value comes from CLI flags, validate with /^\\d{4}$/ before calling parseDate/parseMonth/resolveRange."],"exampleFix":"// before\nconst year = args.year;            // '2026' (string) -> ArgumentError\nresolveRange(year, ...);\n\n// after\nconst year = Number.parseInt(args.year, 10);\nif (!Number.isInteger(year) || year < 1) throw new Error(`bad year: ${args.year}`);\nresolveRange(year, ...);","handlingStrategy":"validation","validationCode":"function coerceYear(raw, label = '年份') {\n  const n = typeof raw === 'string' ? Number.parseInt(raw, 10) : raw;\n  if (!Number.isInteger(n) || n < 1) throw new Error(`${label} must be a positive integer, got: ${raw}`);\n  return n;\n}\n// call before parseDate/parseMonth/resolveRange: coerceYear(args.year)","typeGuard":"function isPositiveInteger(v) {\n  return Number.isInteger(v) && v >= 1;\n}","tryCatchPattern":"try {\n  const range = resolveRange(year, month);\n} catch (e) {\n  if (/非法：.*应为正整数/.test(e.message)) {\n    console.error('Year must be a positive integer, e.g. --year 2026');\n    process.exitCode = 2;\n  } else { throw e; }\n}","preventionTips":["Convert CLI flags with Number.parseInt(value, 10) before use.","Require full 4-digit years; reject 2-digit abbreviations.","Check for undefined/empty flags that coerce to NaN and default them explicitly.","Reuse validateYear (or a shared isPositiveInteger guard) on every year input path."],"tags":["validation","argument-error","date"],"backgroundTag":"invalid-year-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}