缓存里取出来的字符串 JSON.parse 之后直接断言成 User,本地一直正常。线上有一条老缓存没有 nickname 字段,渲染时报 Cannot read properties of undefined。乍看像缓存或者权限的锅,追下去往往不是。
const raw: unknown = JSON.parse(text); const parsed = UserSchema.safeParse(raw); if (!parsed.success) return null; const user: User = parsed.data;
追下去是这么回事:JSON.parse 的返回值本来就是 any,断言只改编译期的看法,不做结构检查。缓存和接口的数据会随版本漂移,类型声明描述的是当前版本而不是线上那份。
「JSON.parse 类型校验」这类改动最怕改一半,回滚脚本先准备好,再动生产。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
具体做法是,把 parse 的返回值声明成 unknown 不要 any;在读取入口用 zod 或手写函数确认字段;关键字段缺失时走默认值 或者丢弃这条缓存;给缓存加版本号 结构变了就换 key。
验收就看一点,缺字段的缓存被识别并跳过 页面不再白屏 日志里能看到失败的字段名。
