Node.js上传图片接口返回数据时出现Unhandled promise rejection报错
问题根因
你代码里有三个核心问题导致触发未捕获Promise拒绝报错:
- 混用了
async/await和Mongoose回调写法:给findByIdAndUpdate传入回调函数后,该方法不会返回Promise,外层加await既拿不到正确返回值,也无法捕获操作抛出的错误,错误直接逃逸触发告警。 - 文件移动方法
pp.mv()是异步操作,你没有等待它执行完成就往下走数据库逻辑,也没有捕获该方法可能抛出的错误(比如目录不存在、文件权限不足、写入失败等),出错时直接触发未处理的Promise拒绝。 findByIdAndUpdate参数顺序写反了:该方法正确参数顺序是(查询条件, 更新数据, 配置项, 回调),你把返回新文档的配置{new: true}放到了更新数据的位置,真正要更新的头像字段{image: namePp}被当成配置项传入,数据库操作本身就会执行异常。
修复后可直接运行的代码
userRouter.post("/upload/:id", async(req, res) => { try { const user_id = req.params.id; const pp = req.files.productImage; const fileExt = pp.name.split('.').pop(); const namePp = `${uuidv4()}.${fileExt}`; // 等待文件写入完成,出错会直接进入catch块 await pp.mv(`./picturesProfile/${namePp}`); // 修正参数顺序,移除回调,纯await写法拿更新后的用户数据 const updatedUser = await User.findByIdAndUpdate( user_id, { image: namePp }, // 第二个参数传要更新的字段 { new: true } // 第三个参数传配置,new:true表示返回更新后的最新文档 ); console.log(updatedUser); res.send({ updatedUser, fileInfo: pp }); } catch (err) { console.error('上传接口处理异常:', err); res.status(500).send({ code: 500, msg: '上传失败,请稍后重试' }); } })
额外注意事项
- 提前确认项目根目录下存在
picturesProfile文件夹,没有的话手动新建,或者启动时用fs模块自动创建,否则文件写入会直接报错。 - Mongoose操作和文件上传这类异步逻辑,统一用
async/await+try/catch的写法捕获错误,不要和回调混用,避免出现错误捕获不到、返回值异常的问题。 - 接口出现错误时一定要给前端返回明确的错误响应,不要只在控制台打印日志就结束,否则前端会一直等待响应直到超时。
内容的提问来源于stack exchange,提问作者Borhen Kalboussi
相关产品推荐
相关产品推荐

