Javascript 捕获异步等待快速路由处理程序中的所有错误

Javascript 捕获异步等待快速路由处理程序中的所有错误,javascript,express,async-await,Javascript,Express,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) .j

假设我有这样一条路线:

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);
};
但这对
异步
路由不起作用,因为它们不直接抛出

例如,这将不起作用:

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!');
}));
但这真的很痛苦,因为现在我必须为每条路线调用这个函数

什么是更好的处理方法


  • 答案正是我上面描述的
  • 对的回答不使用
    wait

基本上,您不希望直接将
异步
函数传递到Express的
app.get
,因为
app.get
不处理函数返回的承诺。因此,您需要包装这些
async
处理程序(正如您所做的那样)

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

const appGet = handler => app.get(asyncRoute(handler));
然后使用它而不是
应用程序。获取

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


在某个时候(可能不是现在),您可能想看看。

您认为使路由回调
异步
有什么好处?Express没有使用承诺,所以。。。它纯粹是为了在它里面获得
wait
语义吗?如果是这样的话,那么你的包装器就是实现这一点的正确方法。(你可能会看到。)我的一些路由需要多个
async
调用(例如数据库、API、bcrypt),因此在
async
上下文中更容易编写。@T.J.Crowder如果我没有通过一个承诺(例如
123
),那么我希望强制承诺(例如,
Promise.resolve(123)
)。请注意,
Promise.resolve(Promise.resolve(x))
被展平为
Promise.resolve(x)
。好的。我不认为有任何理由将非承诺传递到名为
asynchroute
的东西中,所以我没有意识到您想要处理它。:-)