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

Node.js部署API时遇UnhandledPromiseRejectionWarning问题求助

解决UnhandledPromiseRejectionWarning及重复响应问题

错误原因分析

  1. 未处理的Promise拒绝
    你的async函数中,await User.findOne()和await User.findById()没有错误捕获逻辑。一旦数据库查询失败,这些Promise会被拒绝但未被处理,直接触发UnhandledPromiseRejectionWarning。

  2. 逻辑错误导致重复响应/无响应

    • 使用user.friends.find()遍历好友列表是错误的,find的作用是返回第一个匹配元素,而非执行遍历逻辑;且switch分支没有break,会导致多个分支代码被执行,多次调用res.json()发送响应。
    • friend != req.headers.username判断逻辑错误,friend是User对象,应比较friend.username !== req.headers.username。
    • 当user.friends为空数组时,find的回调不会执行,导致请求无响应;若有多个不匹配的好友,会多次进入default分支,重复执行数据库更新和响应发送。

修正后的代码

router.post('/add', async (req, res) => {
  try {
    const friend = await User.findOne({ username: req.body.friend });
    const user = await User.findById(req.body.id);

    // 好友不存在的情况
    if (!friend) {
      console.log(`添加好友失败:用户 ${req.headers.username} 尝试添加不存在的用户`);
      return res.status(404).json({
        status: "Failed",
        message: "抱歉,该用户名不存在",
        data: null
      });
    }

    // 尝试添加自己的情况
    if (friend.username === req.headers.username) {
      return res.status(401).json({
        status: "Failed",
        message: "抱歉,不能添加自己为好友",
        data: null
      });
    }

    // 检查好友已存在的情况
    const isFriendExists = user.friends.some(x => x.friend_username === friend.username);
    if (isFriendExists) {
      return res.status(401).json({
        status: "Error",
        message: "抱歉,该好友已添加",
        data: []
      });
    }

    // 执行添加好友操作
    const result = await User.findByIdAndUpdate(
      req.body.id,
      {
        $addToSet: {
          friends: {
            friend_id: friend.id,
            friend_username: friend.username
          }
        }
      },
      { upsert: true, safe: true, new: true } // new:true 返回更新后的文档
    );

    res.status(200).json({
      status: "Success",
      message: "好友添加成功!",
      data: result
    });

  } catch (err) {
    console.error("数据库错误:", err);
    res.status(500).json({
      status: "Failed",
      message: "数据库错误",
      data: err.message
    });
  }
});

关键修正点

  • 用try/catch包裹所有异步操作,统一处理数据库错误,避免未处理的Promise拒绝。
  • 拆分判断逻辑,每个条件满足后立即返回响应,防止后续代码执行导致重复响应。
  • 用some()替代find()检查好友是否存在,逻辑更清晰且不会重复遍历执行。
  • 将findByIdAndUpdate的then/catch改为await,保持async/await风格统一,代码更易读。
  • 添加new: true选项,让findByIdAndUpdate返回更新后的用户文档。

内容的提问来源于stack exchange,提问作者Tomás Gabriel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:35:18