使用async / await时在Express中捕获未处理的异常

时间:2016-11-28 17:38:05

标签: javascript express typescript error-handling async-await

请注意以下TypeScript代码:

app.get('/test_feature', function (req: Request, res: Response) {
    throw new Error("This is the bug");
});

app.use(logErrors);

function logErrors (err: Error, req: Request, res: Response, next: NextFunction) {
    console.log(err);
    mongoDal.log(err.message, err);
    next(err);
}

在这里,我在请求处理程序中抛出一个错误,并按预期触发logErrors函数。

但是,我改变我的代码以使用异步函数:

app.get('/test_feature', async function (req: Request, res: Response) {
    throw new Error("This is the bug");
    await someAsyncFunction();
});

现在,因为我的函数是异步的,错误以某种方式由Express的默认错误处理程序处理,所以我的自定义错误处理程序没有到达,也没有Node默认错误处理程序:

process.on('uncaughtException', function (err: Error) {
    try {
        console.log(err);
        mongoDal.log(err.message, err);
    } catch (err) {

    }
});

如何制作我的记录错误'在异步函数中发生错误时达到的函数?我想要一个通用的解决方案,而不是在每个请求处理程序中尝试/ catch。

1 个答案:

答案 0 :(得分:6)

这里的问题是你的处理程序不再引发同步异常。相反,您的处理程序返回一个被拒绝的promise。请注意,这不是承诺或异步/等待特定问题,对于使用回调等的任何快速代码来说,这也是一个普遍问题 - 如果您在编写异步代码时不小心处理错误,那么它就是'很容易完全失去它们。

为了在你的情况下处理这个问题,有些事情需要注册,以便从你回来的承诺中得到拒绝。有一些选择:

  1. 明确地向所有错误处理程序添加.catch(),并自行处理错误,或者调用next(err)委派给正常的快速错误处理。
  2. 为您的处理程序创建一个包装函数来执行此操作,并在任何地方使用它。您可以使用现有的wrap()函数,例如express-promise-wrap
  3. 扩展.get和朋友以自动跟踪处理程序返回的承诺中的拒绝。您可以手动执行此操作,但看起来express-as-promised是一个有效的实现(尽管我还没有尝试过)。
  4. 设置起来有点复杂,但是一旦你有了它,我强烈优先考虑3。有了这个,您应该能够将异步函数编写为处理程序,它们将全部返回承诺,并且您的处理程序代码将自动监视这些承诺以防止任何后续失败。

    如果你想进一步阅读,StrongLoop实际上已经有一篇文章更详细地看了这篇文章:https://strongloop.com/strongblog/async-error-handling-expressjs-es7-promises-generators/