2017-03-12 76 views
2

我正在开发中的Node.js后端应用程序,我有以下问题遇到:当开发者调用函数的诺言象下面这样:承诺 - 未处理拒绝挂起请求

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

上面的代码会做的事情,但它从开发requiers写在上面每条路由代码,所以它不是很干净的解决方案。

我还试图用错误的中间件:

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
+0

“*从开发商requiers写在上面每一个路线*代码” - 然后把一个'get'中的抽象本身 – Bergi

回答

0

为什么不只是提供一个包装的功能,每个人都可以使用

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,并提供一个更短的抽象

+0

你确定'await'可以用在非'async'函数中吗? –

+0

你是对的,对不起,修好了 –

相关问题