调用特定路由后出现TypeError: error.status is not a function报错如何解决
错误产生原因
- 错误处理中间件参数顺序异常或代码笔误:Express的错误处理中间件必须严格按照
(error, req, res, next)的4参数顺序定义,如果参数顺序写反(比如写成(req, res, error, next)),第三个参数会被赋值为Express内置的next函数,此时尝试调用error.status就会触发不是函数的报错。另外如果手滑把res.status()写成error.status()也会触发相同报错。 - signup路由Promise链缺失根捕获:当前你仅为
user.save()操作添加了catch,最外层User.find().exec()的执行错误没有捕获逻辑,异常会直接抛到错误处理中间件触发执行。 - 依赖版本不兼容:你使用的
bcrypt@5.0.1最低支持Node.js 12版本,和你当前的Node 10.19.0不匹配,bcrypt执行哈希操作时会抛出非标准异常,进一步放大错误处理逻辑的问题。
解决方案
按以下步骤逐一修复即可:
1. 修正错误处理中间件
首先将错误处理中间件移到所有路由、其他中间件的最后面,严格按照4参数顺序定义,同时增加参数类型校验避免异常:
app.use((error, req, res, next) => { // 校验status类型,避免传入非数值 const status = typeof error.status === 'number' ? error.status : 500 res.status(status) res.json({ error: { message: error.message || '服务器内部错误' } }) console.log(error) })
2. 补全signup路由的异常捕获
给最外层的User.find()操作添加catch逻辑,避免未捕获的Promise rejection:
router.post("/signup", (req, res, next) => { User.find({ email: req.body.email }) .exec() .then(user => { if (user.length >= 1) { return res.status(409).json({ message: "Mail exists" }); } else { bcrypt.hash(req.body.password, 10, (err, hash) => { if (err) { return res.status(500).json({ error: err }); } else { const user = new User({ _id: new mongoose.Types.ObjectId(), email: req.body.email, password: hash }); user .save() .then(result => { console.log(result); res.status(201).json({ message: "User created" }); }) .catch(err => { console.log(err); res.status(500).json({ error: err }); }); } }); } }) // 新增根异常捕获 .catch(err => { console.log(err) res.status(500).json({ error: err }) }) });
3. 替换兼容的bcrypt版本
执行以下命令降级bcrypt到支持Node 10的稳定版本:
npm uninstall bcrypt npm install bcrypt@3.0.8
内容的提问来源于stack exchange,提问作者edoardo
相关产品推荐
相关产品推荐

