快速错误处理和异步等待

时间:2017-01-10 13:28:58

标签: javascript node.js express asynchronous promise

在我的Node.js应用程序中,我添加了以下代码来捕获每个未捕获的异常:

dataTable

问题是Express有自己的默认错误处理程序,可以捕获每个未捕获的异常。现在,Express在Node(process.on)之前捕获了异常,因此我的记录器没有达到。但是,可以在Express之前添加另一个可以捕获每个异常的错误处理程序:

process.on('uncaughtException', function (err: Error) {
    try {
        logger.err(err);
    } catch (err) {

    }
});

这仍然不能涵盖每一个案例。每当我使用app.use(logErrors); function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { logger.err(err); next(err); } 调用async function时,都没有异常,但会返回被拒绝的Promise。例如:

await

没有达到我的app.get('/foo', async function (req: Request, res: Response, next: NextFunction) { await bar(); }); function bar() { throw new Exception(); } 功能,因为它不会投掷,但会返回被拒绝的承诺。

为了解决这个问题,我用另一个函数包装了我的Express HTTP处理程序:

logErrors

next(错误)将错误传递给我的处理程序。现在,我设法捕获app.get('/foo', wrap(async function (req: Request, res: Response, next: NextFunction) { await bar(); })); function wrap(func: (req: Request, res: Response, next: NextFunction) => void) { return async function (req: Request, res: Response, next: NextFunction) { try { await func(req, res, next); } catch (err) { next(err); } } } 函数的例外情况。

我差不多完成了。我还有一个案例,我无法捕捉到这些错误。当我在没有logErrors关键字的情况下调用async function时会发生这种情况(有时在代码的两个不同位置使用相同的函数,一次异步调用,一次同步调用)。所以这段代码不会发现错误:

await

这里发生的事情是Express HTTP处理程序将已解析的Promise返回给app.get('/foo', wrap(async function (req: Request, res: Response, next: NextFunction) { bar(); })); 函数。反过来,换行功能不会到达wrap块,因此它不会调用catch来到我的记录器。

next(err)函数依次返回一个被拒绝的Promise,但是没有人等待它的返回值。

如何以这样的方式更改我的代码?我最终无法处理任何未处理的Promise拒绝? (只有通用解决方案)

3 个答案:

答案 0 :(得分:2)

您可以为unhandledRejection设置另一个process.on事件。

您可以使用它来处理整个代码中的拒绝。

注意:记住在记录所需内容后终止进程。有关here的更多信息。

答案 1 :(得分:1)

我找到了解决方案:

app.get('/foo', async function (req: Request, res: Response, next: NextFunction) {
    dontAwait(() => bar());
});

async function dontAwait(func: () => void) {
   try {
       await func();
   }
   catch (err) {
     logErrors(err);
   }
}

答案 2 :(得分:1)

  

我还有一个案例,我无法发现错误。

你可以,但你目前根本不对结果做任何事情。如果您希望触发常用的错误处理程序,则需要await

  

当我在没有async function关键字

的情况下拨打await时会发生这种情况

我看不出有什么好的理由。但如果你真的想要fire and forget the function,你就可以做到。您只需要明确处理错误:

bar().catch(e => logger.err(e));