承诺 – 未处理的拒绝挂起请求

我在Node.js中开发一个后端应用程序,遇到以下问题:开发人员调用如下所示的promise函数:

mainRouter.get("/xD", async (req, res) => { res.send(await this.fooService.foo()); }); 

有可能this.fooService.foo()函数将失败(承诺拒绝),最终用户将得到请求超时。

我想确保开发人员的错误不会导致UnhandledPromiseRejectionWarning(最后超时错误)。 问题是如何configuration应用程序来logging错误,并在出现UnhandleRejection时将状态500返回给用户。

我试过的:

 mainRouter.get("/xD", async (req, res) => { try { res.send(await this.fooService.foo()); } catch (err) { res.status(500).send("error"); } }); 

上面的代码会做的事情,但开发人员要求在每个路线上面写代码,所以这不是一个干净的解决scheme。

我也试图使用错误中间件:

 mainRouter.use((err:any, req, res, next) => { console.log(err); res.status(500).send("Error"); }); 

但是没有收到PromiseRejection

最后,我创build了注册unhandledRecejtion事件的函数处理程序的中间件:

 mainRouter.use((req, res, next) => { process.on('unhandledRejection', (reason, p) => { console.log(reason); res.status(500).send("Error"); }); next(); }); 

我不确定node.js中的stream程事件是如何工作的,但是恐怕上面的代码会导致场景的问题:

  1. 第一个请求产生未处理的承诺拒绝
  2. 注册处理程序最后的最新请求将返回到用户状态500。

为什么不提供一个每个人都可以使用的包装函数

 async function wrapAsync(res, asyncFn) { try { res.send(await asyncFn()); } catch (err) { res.status(500).send("error"); } } 

asyncFn是一个返回promise的函数

然后其他开发人员可以简单地使用它

 mainRouter.get("/xD", async (req, res) => await wrapAsync(res, this.fooService.foo)); 

也可能覆盖mainRouter.get并提供更短的抽象