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

Node.js中mongoose的findOneAndUpdate执行成功却返回错误该如何解决

问题根因

你遇到的报错核心是同时混用了await异步语法和回调函数两种处理findOneAndUpdate结果的方式,导致Mongoose执行逻辑冲突,同时可能触发重复响应的报错:

  • 当给findOneAndUpdate传入回调参数时,方法不会返回Promise对象,此时外层的await不会生效,同时回调函数和外层的catch块都可能尝试给前端返回响应,同一请求两次调用res.send/res.json就会抛出服务端错误。
  • 数据库可以正常更新是因为Mongoose的查询逻辑本身执行完成了,错误出现在结果返回的节点,属于异步处理逻辑冲突导致的响应异常。

修复方案

方案1:保留await,去掉回调函数(推荐,符合现代异步代码写法)

try {
  const docs = await userModel.findOneAndUpdate(
    { _id: req.params.id },
    {
      $set: {
        nickName: req.body.nickName,
      },
    },
    { upsert: true, new: true, setDefaultsOnInsert: true }
  );
  return res.send(docs);
} catch (err) {
  return res.status(500).json({ message: err });
}

方案2:保留回调,去掉await

// 去掉await关键字,完全用回调处理结果
userModel.findOneAndUpdate(
  { _id: req.params.id },
  {
    $set: {
      nickName: req.body.nickName,
    },
  },
  { upsert: true, new: true, setDefaultsOnInsert: true },
  (err, docs) => {
    if (!err) return res.send(docs);
    else return res.status(500).send({ message: err });
  }
);

额外校验点

如果修改后还是报错,可以额外检查两个常见问题:

  • 确认req.params.id是合法的MongoDB ObjectId格式,或者你在userModel的_id字段定义为非ObjectId类型(比如自定义字符串)
  • 确认接口路由的请求方法、参数传递符合预期,req.body.nickName没有触发schema字段校验规则报错

内容的提问来源于stack exchange,提问作者Kenyuki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:27:05