在我的Node.js应用程序中,我添加了以下代码来捕获每个未捕获的异常:
process.on('uncaughtException', function (err: Error) { try { logger.err(err); } catch (err) { } });
问题是Express有自己的默认错误处理程序,它捕获每个未捕获的异常.现在,Express在Node(process.on)之前捕获了异常,因此我的记录器没有到达.但是,可以在Express之前添加另一个可以捕获每个异常的错误处理程序:
app.use(logErrors); function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { logger.err(err); next(err); }
这仍然不包括每一个案例.每当我async function
打电话给我时await
,都没有例外,但是会返回被拒绝的Promise.例如:
app.get('/foo', async function (req: Request, res: Response, next: NextFunction) { await bar(); }); function bar() { throw new Exception(); }
将无法达到我的logErrors
功能,因为它不会抛出,但会返回被拒绝的Promise.
所以为了修复它,我用另一个函数包装了我的Express HTTP处理程序:
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); } } }
next(错误)将错误传递给我的处理程序.现在,我设法捕获我的logErrors
功能的例外.
我就快完成了.我还有一个案例,我无法发现错误.当我调用async function
没有await
关键字的时候会发生这种情况(有时在代码中的两个不同位置使用相同的函数,一次异步调用,一次同步调用).所以这段代码不会捕获错误:
app.get('/foo', wrap(async function (req: Request, res: Response, next: NextFunction) { bar(); }));
这里发生的是Express HTTP处理程序将已解析的Promise返回给wrap
函数.依次包裹函数不会到达catch
块,因此它不会调用next(err)
到达我的记录器.
bar
反过来,函数返回一个被拒绝的Promise,但是没有人等待它的返回值.
如何以这样的方式更改我的代码我不会以任何未处理的Promise拒绝结束?(只有通用解决方案)