You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Mongoose至5.0.13后,angular-fullstack应用出现Bluebird相关500错误

解决Mongoose 5升级后更新操作抛500错误的问题

这个问题我之前帮人排查过,本质是Mongoose 5.x对更新类方法的返回值和行为做了不少改动,而angular-fullstack生成的代码还是沿用了Mongoose 4的写法,导致代码处理返回值时出现「expecting an arr...」这类数组相关的错误。

核心原因

Mongoose 4和5在更新方法(比如update、findByIdAndUpdate、bulkWrite)的返回值结构上差异很大:

  • Mongoose 4中,部分更新方法会返回文档数组或者旧文档;
  • Mongoose 5中,这类方法默认返回的是操作结果对象(比如WriteResult、BulkWriteResult),包含nModified、insertedCount等统计属性,不再直接返回文档数组。

而你代码里大概率还在对这些返回值做数组操作(比如判断length、调用forEach),自然会抛出「期望数组」的类型错误。

具体修复步骤

1. 定位报错的更新接口

先找到抛出500错误的API路由代码(比如server/api/xxx/index.js里的update方法),看是用了哪个Mongoose方法导致的。

2. 针对不同更新方法调整代码

这里举几个常见的修复例子:

例子1:findByIdAndUpdate的适配

原来Mongoose 4的写法(默认返回旧文档):

Thing.findByIdAndUpdate(req.params.id, req.body, (err, thing) => {
  if (err) return handleError(res, err);
  if (!thing) return res.status(404).send('Not Found');
  res.json(thing);
});

Mongoose 5中虽然默认返回新文档,但建议显式指定{new: true}确保一致性,同时如果需要验证更新字段,加上runValidators: true:

Thing.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true })
  .then(thing => {
    if (!thing) {
      return res.status(404).send('Not Found');
    }
    res.json(thing);
  })
  .catch(err => handleError(res, err));
例子2:update/updateOne的适配

原来Mongoose 4用update的写法(可能期望返回数组):

Thing.update({ _id: req.params.id }, req.body, (err, results) => {
  if (err) return handleError(res, err);
  if (results.length === 0) return res.status(404).send('Not Found');
  res.json(results);
});

Mongoose 5中update已被废弃,改用updateOne,并且返回的是操作结果对象,要通过nModified判断是否更新成功:

Thing.updateOne({ _id: req.params.id }, req.body, { runValidators: true })
  .then(result => {
    if (result.nModified === 0) {
      return res.status(404).send('Not Found');
    }
    // 如果需要返回更新后的文档,额外查询一次
    return Thing.findById(req.params.id);
  })
  .then(thing => res.json(thing))
  .catch(err => handleError(res, err));
例子3:bulkWrite的适配

如果是bulkWrite相关的错误,注意Mongoose 5返回的是BulkWriteResult对象,不要把它当数组处理:

const operations = [
  // 你的批量操作,比如updateOne、insertOne等
];

Thing.bulkWrite(operations)
  .then(result => {
    // 用result里的统计属性判断结果,比如modifiedCount、insertedCount
    res.json({
      success: true,
      updated: result.modifiedCount,
      inserted: result.insertedCount
    });
  })
  .catch(err => handleError(res, err));

3. 额外注意事项

  • Mongoose 5默认启用了strictQuery,如果你的查询里有schema定义外的字段,会被自动过滤,需要的话可以在schema里设置strictQuery: false;
  • 检查handleError函数是否适配Mongoose 5的错误格式,比如错误对象的属性是否有变化;
  • 所有模型的schema定义,检查是否有Mongoose 5不兼容的选项(比如required的布尔值写法是兼容的,但部分旧的自定义验证器可能需要调整)。

内容的提问来源于stack exchange,提问作者S. Hussey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:40:51