Node.js部署API时遇UnhandledPromiseRejectionWarning问题求助
解决UnhandledPromiseRejectionWarning及重复响应问题
错误原因分析
未处理的Promise拒绝
你的async函数中,await User.findOne()和await User.findById()没有错误捕获逻辑。一旦数据库查询失败,这些Promise会被拒绝但未被处理,直接触发UnhandledPromiseRejectionWarning。逻辑错误导致重复响应/无响应
- 使用
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
相关产品推荐
相关产品推荐

