3.3.2 Bug 定位与修复
定位与修复 Bug 的核心思路是“复现 → 缩小范围 → 找到根因 → 验证修复”。下面用一个前端页面显示异常的 Bug 说明完整过程。
Bug 描述
某项目管理系统的任务看板中,任务卡片上的“截止日期”字段在部分卡片上显示为 Invalid Date,而其他卡片显示正常。
1. 稳定复现
打开看板,刷新页面三次,始终有 3 张卡片显示 Invalid Date。标记出这些任务,确认它们在数据库中的 deadline 字段值分别为:2025-04-31、2025-02-29、2025-06-00。
——这些是无效日期,问题很可能出在数据层面,而不是前端格式化逻辑。
2. 信息收集与范围缩小
- 查看前端代码,日期格式化使用了
new Date(deadline).toLocaleDateString()。 - 在浏览器控制台直接执行
new Date('2025-04-31'),返回Invalid Date,说明 JavaScript 的 Date 对象无法解析不存在的日期。 - 检查后端 API 返回的数据,
deadline字段直接是数据库中存储的字符串,没有做任何校验或转换。
结论:问题根因是数据库中存在非法日期字符串,而前后端均未校验日期有效性。
3. 定位根因
进一步查询是哪些入口写入了这些错误日期。发现在“批量导入任务”功能中,Excel 解析后直接调用保存接口,未校验日期的真实存在性(例如 4 月 31 日本身不存在)。同时数据表定义该字段为 VARCHAR,而非 DATE 类型,导致非法值直接落库。
根因概括:
- 数据库字段类型宽松(应为
DATE) - 导入接口缺少日期校验
- 前端直接展示后端返回值,未做容错
4. 修复方案
采用“治本为主,治标为辅”的策略:
- 数据修复(治标):找到所有错误日期,人工修正为合理日期(如将
2025-04-31纠正为2025-04-30)。 - 后端校验(治本①):在批量导入的保存逻辑中增加日期校验,使用
moment(dateStr, 'YYYY-MM-DD', true).isValid()判断,无效日期返回具体错误提示,拒绝保存。 - 数据库优化(治本②):将
deadline字段类型改为DATE,上线前通过ALTER TABLE配合STR_TO_DATE转换已有合规数据,非法值存量数据先清洗。 - 前端容错(兜底):展示日期前使用一个工具函数:
function formatSafeDate(dateStr) {
const date = new Date(dateStr);
return isNaN(date.getTime()) ? '日期待定' : date.toLocaleDateString();
}
这样即使数据异常,页面也不会出现 Invalid Date,体验更好。
5. 验证修复
- 开发环境重新导入同一份 Excel,系统正确拦截并指出具体行和错误字段。
- 查看数据库,新增任务
deadline均为有效 DATE 值。 - 修复后的看板中,之前显示异常的卡片变为“日期待定”,用于标记存量脏数据,后续集中清洗。
- 回归测试批量导入、手动创建、编辑任务等关联功能,无新问题。
小结
一个 Invalid Date Bug 的定位,从界面现象快速推断到数据层,再追踪到写入入口,最终在数据、接口、UI 三层设防。实际工作中,Bug 定位关键是稳定复现 + 逐层排除,修复则要根源解决并设好兜底,才能避免同类问题再次出现。