代码之家  ›  专栏  ›  技术社区  ›  Basti

如何使用express.Router实例进行错误处理

  •  0
  • Basti  · 技术社区  · 5 年前

    documentation ,任何nodejs express中间件功能都可以被应用程序或路由器实例替换:

    由于路由器和应用程序实现了中间件接口,您可以使用 它们就像任何其他中间件功能一样。

    这是我使用的一些通用错误处理:

    express()
        .use('/test', new TestRouter())
        .use((err, req, res, next) => {
            console.error(err.stack);
            res.status(500).send(err.message);
        })
        .listen(PORT);
    

    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);
    

    为什么这不按预期工作,我怎么能解决呢?

    1 回复  |  直到 5 年前
        1
  •  3
  •   James    5 年前

    错误处理程序需要配置为对 use docs

    在其他app.use()和路由调用之后,最后定义了错误处理中间件;

    我想说的是“路由”也会存储路由器,因此你试图做的事情看起来不受支持。


    进一步深入研究一下,我认为问题在于路由器有独立的层堆栈。在幕后表达实际上只是 Router (我们看到了 here 这是在哪里设置的,然后再往下看中间件在哪里 delegated 在路由器上)。在内部,中间件功能被表示为“层”(如图所示 here )看着 constructor ,我们可以看到路由器有自己的堆栈。

    因此,请考虑以下示例:

    express()
      .use(new RouterA())
      .use(new RouterB())
      .use((err, req, res, next) => {
        ...
      })
      .listen(PORT);
    

    从源头上看,可以认为:

    express()
      .use((req, res, next) => {
        router.handle(req, res, next);
      })
      .use((req, res, next) => {
        router.handle(req, res, next);
      })
      .use((err, req, res, next) => {
        ...
      });
    

    RouterA ,路由器将首先检查自己的中间件堆栈是否有匹配的错误层(即 (err, req, res, next) 函数)并执行该操作,它将冒泡到应用程序级别并执行相同的操作。

    因此,以您的示例为例,如果您考虑翻译的代码,这就解释了为什么它不会在第二个路由器中捕获您的错误处理程序-路由器签名与错误处理程序签名不匹配,因此将跳过它。

    推荐文章