承诺 – 未处理的拒绝挂起请求
我在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程事件是如何工作的,但是恐怕上面的代码会导致场景的问题:
- 第一个请求产生未处理的承诺拒绝
- 注册处理程序最后的最新请求将返回到用户状态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
并提供更短的抽象