Bas*_*sti 5 javascript error-handling node.js express
根据文档,任何nodejs Express中间件功能都可以替换为App或Router实例:
由于路由器和应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们。
这是我使用的一些通用错误处理:
express()
.use('/test', new TestRouter())
.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send(err.message);
})
.listen(PORT);
Run Code Online (Sandbox Code Playgroud)
我尝试用错误处理路由器替换错误处理,但现在回调永远不会执行,并且 Express 使用它的默认错误处理。
const handler = new express.Router();
handler.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send(err.message);
});
express()
.use('/test', new TestRouter())
.use(handler)
.listen(PORT);
Run Code Online (Sandbox Code Playgroud)
为什么这没有按预期工作,我该如何解决它?
use根据文档,错误处理程序需要配置为最后一次调用
最后定义错误处理中间件,在其他 app.use() 和路由调用之后;
我想说“路由”也包含路由器,因此您尝试做的事情看起来不受支持。
只是进一步深入研究这一点,我相信问题归结于路由器具有单独的层堆栈这一事实。Express 在幕后实际上只是一个Router(我们在这里看到它的设置位置,然后进一步向下将中间件委托给路由器)。在内部,中间件函数表示为“层”(如此处所示),查看构造函数,我们可以看到路由器有自己的堆栈。
因此,请考虑以下示例:
express()
.use(new RouterA())
.use(new RouterB())
.use((err, req, res, next) => {
...
})
.listen(PORT);
Run Code Online (Sandbox Code Playgroud)
通过查看源码,可以将其视为:
express()
.use((req, res, next) => {
router.handle(req, res, next);
})
.use((req, res, next) => {
router.handle(req, res, next);
})
.use((err, req, res, next) => {
...
});
Run Code Online (Sandbox Code Playgroud)
因此,如果在 中抛出错误RouterA,路由器将首先检查其自己的中间件堆栈中是否有匹配的错误层(即函数(err, req, res, next))并执行它,然后它会冒泡到应用程序级别并执行相同的操作。
因此,给出您的示例,如果您考虑翻译后的代码,这解释了为什么它不会在第二个路由器中捕获您的错误处理程序 - 路由器签名与错误处理程序的签名不匹配,因此它将被跳过。