AI 辅助开发踩坑录:跨项目反复出现的 8 类问题
在多项目、长时间使用 AI 编程助手协作开发的过程中,一些同类型的坑反复出现——它们跨越技术栈与业务领域,几乎每个项目都要踩一遍。本文汇总其中最高频的 8 类问题,附具体现象、根因与修复方法。
一、pkill -f 会杀掉执行它的 shell 自身
现象:执行重启服务的命令后”没有任何输出”,命令像是被中断了,很容易误判为服务本身的问题。
根因:pkill -f "node dist/main.js" 会匹配所有命令行字符串包含该模式的进程——包括执行这条 pkill 的 shell 自己(它的命令行里就含有这个字符串)。
正确做法:
1 | # 方法一:方括号技巧,让模式匹配不到自身 |
这个坑在至少 8 个不同项目的备忘里出现过,属于”最简单也最容易重复踩”的一类。
二、时间与时区处理
三个方向都出过问题:
toISOString()是 UTC 时间:东八区凌晨 0–8 点执行时,日期会比本地”差一天”——单据日期、打卡记录、编号年月全部受影响;- 字符串比较
' ' < 'T'是系统性问题:2026-08-30T...(ISO 格式)与2026-08-30 ...(SQLite datetime 格式)直接做字符串比较,两个方向都会错——曾导致登录限流闸永远查不到记录、订单归因静默丢单、逾期预警提前误报; date(completed_at)按 UTC 切天:北京 00:00–08:00 的完工被算进前一天,计件工资统计错位。
统一方案:所有业务时间处理走本地时区格式化函数(如 todayLocal()),或改用毫秒时间戳比较:
1 | // 统一为同一种字符串格式再比较 |
三、批量替换 / 正则改写必须回头验证
批量文本替换的”静默失败”和”误伤”是两个方向的坑:
- 批量
sed把 helper 函数自身的实现替换成了对自身的调用 → 无限递归(RangeError: Maximum call stack size exceeded),112 处建表函数全部失效; - Python 批量替换因缩进不匹配(4 空格 vs 8 空格)静默失败,残留语法错误还照样提交;
- 文本替换误吞相邻行,把
const status、函数声明整行弄丢。
做法:
- 用带断言的替换(匹配失败立即报错,而不是静默跳过);
- 替换后读回整个文件校验;
- 特别检查 helper 自身是否被波及。
四、静默失败比报错更危险
ValidationPipe({ whitelist: true })会把未挂 class-validator 装饰器的字段静默剔除——筛选参数、查询条件全部失效,接口不报错但结果不对;- 前端
catch(() => null)把接口错误吞成 null,UI 照常渲染(错误被完全掩盖); saveChatMessage不检查response.ok,落库失败静默发生,刷新即丢;- 小程序 toast 与 loading 共享原生气泡,批量上传中的失败提示被立即覆盖,用户完全无感知。
原则:凡是”失败后继续跑”的代码路径,必须有明确的错误信号(日志 / 状态返回 / UI 提示),宁可报错也不要静默。
五、”构建通过 / URL 可达”不等于功能可用
- 自动化页面走查若只断言 URL 与”无横向溢出”,白屏页也会全部通过;
- 构建产物未设置生产环境标识时,打出来的是 Preview 身份、连的是测试后端;
vite build不会覆盖未注册路由的新页面——页面存在但构建图中没有它。
做法:断言页面内容而非 URL;用真实浏览器验证”能不能用”,而不是”能不能打开”。
六、开发环境缓存造成的假象
vitedev server 加载缓存旧模块,源码已改但页面不生效(重启 dev server 解决);- 浏览器磁盘缓存旧 JS:
?v=2只作用在 HTML 上,<script src>相对路径不带 query → 换端口(新 origin)才生效; - Prisma 改 schema 后未
generate就 build,报错信息与真实原因完全不匹配。
记忆点:改了没生效 → 先怀疑缓存,再怀疑代码。
七、npm 新安装脚本安全策略
较新的 npm 默认拦截依赖的 install/postinstall 脚本:
1 | # 单包放行(包名作为位置参数放在前面) |
注意 ~/.npmrc 的 allow-scripts= 是白名单语义——写了 A 包,B 包的安装脚本也会被拦(bcrypt / esbuild / prisma 都受影响)。常驻方案建议只放行确实需要的单个包。
八、数据库层高频陷阱
- Decimal 序列化成字符串:
1200变成"1200.00",前端数字输入组件与算术全部出错; COUNT(*)返回 BigInt:JSON 序列化直接崩溃;- MySQL 列名大小写不敏感:
userId与userid同时出现即报重复列,迁移中途失败; varchar(191)存不下富文本:公告/公文正文会超长被拒,且 TEXT 列不能有默认值。
做法:金额字段在序列化层统一还原为数字;COUNT 结果显式转 Number;命名规范里提前规避大小写歧义;富文本列从一开始就上 TEXT。
总结
这 8 类问题的共同点:它们都不在”正常路径”上,跑通一次就不会再注意到,直到在生产环境以更难排查的形态暴露。把它们固化成检查清单,在代码审查与验收时逐条对照,比每次重新踩一遍划算得多。