Express使用app.use注册作用域路由时的错误传递处理问题
Express作用域路由错误捕获问题解答
问题1:如何让路由中产生的错误被下游全局错误处理中间件捕获
你只要遵循Express的错误传递规则即可,步骤如下:
- 首先纠正你现有代码的基础错误:
- 注册路由的代码写错了,第二个参数是你引入的
blogRoutes变量,不是字符串,修改为:app.use('/blogs', blogRoutes) - 全局错误处理中间件必须是4个参数,Express才会识别它为错误处理中间件,你现在写的是3个参数,无法捕获上游传的错误,修改为:
// 全局错误处理中间件,必须保留4个参数的顺序 app.use((err, req, res, next) => { console.error(err.stack) // 可选:打印错误栈方便排查 res.status(err.status || 404).render('404', {title: '404', error: err }); });- 你现有普通路由里无意义的
next(err)要删掉,比如res.redirect('/blogs')之后你没定义err变量,直接调用next(err)会直接抛出未定义错误,正常处理完请求不需要调用next,只有捕获到错误的时候才调用next(错误对象)传递错误。
- 注册路由的代码写错了,第二个参数是你引入的
- 然后在
blogRoutes路由模块里,所有路由处理函数捕获到错误时都调用next(err)传递错误即可,示例:// ./route/blogroutes.js 里的写法示例 const express = require('express') const router = express.Router() const Blog = require('../models/blog') // 假设你定义了Blog模型 // 普通回调写法 router.get('/', (req, res, next) => { Blog.find() .then(blogs => res.render('blogs/index', { blogs })) .catch(err => next(err)) // 捕获数据库错误,传递给下游错误处理 }) // async/await写法 router.get('/:id', async (req, res, next) => { try { const blog = await Blog.findById(req.params.id) res.render('blogs/detail', { blog }) } catch (err) { next(err) // 捕获错误传递 } }) module.exports = router
只要按上面的写法,作用域路由里的所有错误都会自动穿透到全局错误处理中间件。
问题2:是否可以用app.use('/blogs', blogRoutes, (err, req, res, next) => {next(err)})的写法实现需求
可以,但完全没必要。
这种写法属于/blogs前缀的局部错误处理中间件,只有当你需要对博客路由的错误做专属预处理(比如单独打日志、加专属错误标识)的时候才需要加,如果你只是要把错误透传给全局错误处理,不需要额外写这个中间件,只要blogRoutes里正确调用next(err),错误会自动向下传递到全局错误处理。
内容的提问来源于stack exchange,提问作者Ambient Soda
相关产品推荐
相关产品推荐

