MongoDB调用push报Cannot read property 'push' of undefined的解决方法
报错原因
你遇到的Cannot read property 'push' of undefined错误和productId逻辑无关,核心原因是代码中执行push操作的user.usersOrder值为undefined,不是可调用数组方法的数组类型,常见触发场景有三个:
User.findById(data.userId)没有查询到匹配userId的用户文档,返回值为null,访问null.usersOrder会得到undefined- 匹配到的用户文档中本身不存在
usersOrder字段,或该字段存储类型不是数组(比如存为对象、字符串、null值) - User模型的Schema中未声明
usersOrder字段,且未开启strict: false配置,Mongoose返回的文档对象不会挂载未声明的字段,直接访问即为undefined
另外原代码还存在两处逻辑问题,会导致异常捕获失效:
- 混用
await与.then()链式写法,没有对查询返回的user做空值判断,查询无结果时会直接触发报错 - Mongoose的
save()方法返回Promise,执行成功后then回调只会返回保存完成的文档对象,错误需要通过catch或try/catch捕获,你原代码中写在then第二个入参位置的error永远无法拿到实际错误信息
修正后代码
let isUserIdPush = false; // 查询目标用户 const user = await User.findById(data.userId); // 处理用户不存在的场景 if (!user) { console.log('匹配userId的用户不存在'); return isUserIdPush; } // 兜底初始化usersOrder字段,避免存量文档无该字段导致的push报错 if (!Array.isArray(user.usersOrder)) { user.usersOrder = []; } // 推入商品ID user.usersOrder.push({ productId: data.productId }); // 保存并捕获异常 try { await user.save(); isUserIdPush = true; } catch (err) { console.error('用户订单信息保存失败:', err); isUserIdPush = false; }
补充说明
如果你已经在Schema中给usersOrder设置了默认值[],依然需要加数组类型判断的兜底逻辑:在添加usersOrder字段之前创建的存量用户文档,本身不会自带该字段,查询后直接访问依然可能出现undefined的情况。
内容的提问来源于stack exchange,提问作者Jose Manuel
相关产品推荐
相关产品推荐

