【问题标题】:promises - unhandled rejection hangs request承诺 - 未处理的拒绝挂起请求
【发布时间】:2017-08-02 17:33:06
【问题描述】:

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

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

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

我想确保开发人员的错误不会导致 UnhandledPromiseRejectionWarning(最后是超时错误)。问题是如何配置应用程序在 UnhandleRejection 发生时记录错误并向用户返回状态 500。

我尝试了什么:

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

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

我也尝试过使用错误中间件:

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

但它没有捕获 PromiseRejection

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

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

我不确定 node.js 中的流程事件是如何工作的,但我担心上面的代码会导致场景出现问题:

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

【问题讨论】:

  • "它要求开发者在每条路径中编写上述代码" - 然后在 get 本身中添加一个抽象

标签: node.js express promise async-await


【解决方案1】:

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

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

其中 asyncFn 是一个返回承诺的函数

那么其他开发者就可以这么简单的使用了

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

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

【讨论】:

  • 你确定await可以用在非async函数中吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 2023-03-17
  • 2018-04-01
相关资源
最近更新 更多