首页 > 解决方案 > 捕获 async-await 快速路由处理程序中的所有错误

问题描述

假设我有这样的路线:

app.get('/broken', (req, res) => {
  throw new Error('Broken!');
});

这永远不会向客户端发送响应。

但是,我可以为所有错误添加一个中间件:

const errorMiddleware = (error, req, res, next) => {
  if (error) {
    console.error(error);
    return res.status(500)
      .json({
        message: 'Internal server error', 
      });
  }
  next(error);
};

但这不适用于async路线,因为它们不throw直接。

例如,这将不起作用:

app.get('/broken', async (req, res) => {
  throw new Error('Broken!');
});

所以我可以像这样创建一个包装器:

const asyncRoute = f => (req, res, next) => {
  return Promise.resolve(f(req, res, next)).catch(next);
};

app.get('/broken', asyncRoute(async (req, res) => {
  throw new Error('Broken!');
}));

但这真的很痛苦,因为现在我必须为每条路线调用这个函数!

有什么更好的方法来处理这个?


标签: javascriptexpressasync-await

解决方案


从根本上说,您不想直接将async函数传递给 Express 的app.get,因为app.get不处理函数返回的承诺。所以你需要包装这些async处理​​程序(就像你正在做的那样)。

您可以通过在模块顶部给自己一个实用方法来避免每次都这样做:

const appGet = handler => app.get(asyncRoute(handler));

然后用它代替app.get

appGet('/broken', async (req, res) => {
  throw new Error('Broken!');
});

在某些时候(可能不是现在),您可能想查看Koa


推荐阅读