express-validator校验邮箱已存在时返回提示且避免服务崩溃
问题根因
服务崩溃是因为异步路由抛出的异常未被正确捕获传递:
signup是async异步函数,校验失败throw error的逻辑写在了try...catch块外部,抛出的异常属于未捕获的Promise rejection,不会被Express默认的错误处理逻辑接收,会直接导致Node.js进程退出。- 密码不一致的分支返回响应后没有终止函数执行,后续逻辑运行时会触发"已发送响应后重复发送"的报错。
修复方法
- 将参数校验逻辑移入
try...catch块覆盖范围内,确保抛出的错误能被catch捕获,再通过next(err)传递给全局错误处理中间件。 - 密码校验返回响应前添加
return,阻断后续逻辑执行,避免重复响应问题。
修正后的signup方法代码如下:
const { validationResult } = require("express-validator"); exports.signup = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { const error = new Error('Validation failed.'); error.statusCode = 422; error.data = errors.array(); throw error; } const { firstName, lastName, email, mobile, password, confirmPassword } = req.body; if (password !== confirmPassword) { return res .status(422) .json({ message: "Password and confirm password must be same" }); } // 保存用户并返回前端响应的逻辑写在这里 } catch (err) { if (!err.statusCode) { err.statusCode = 500; } next(err); } };
修改后,校验触发的错误会被catch捕获,传递到你在app.js中配置的全局错误处理中间件,正常返回422状态码和错误信息,不会再导致服务崩溃。
如果不想调整校验逻辑的位置,也可以直接把校验失败处的throw error替换为next(error),同时在调用后加return终止函数执行,效果一致。
内容的提问来源于stack exchange,提问作者psudo
相关产品推荐
相关产品推荐

