You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express的async-await路由处理器中捕获所有错误?

Express全局错误中间件对异步路由无效的问题解决

嘿,这个问题我之前也踩过坑!咱们一步步拆解问题,再给出实用的解决方案~

先理清楚同步路由的正常情况

你写的这条同步路由:

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

确实能被你定义的全局错误中间件捕获到,因为同步代码里抛出的错误会直接进入Express的错误处理流程。你的中间件代码本身是没问题的:

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

不过要注意,这个中间件必须注册在所有路由之后,不然也会失效哦。

为啥异步路由抓不到错误?

当你用async/await写异步路由时,比如:

app.get('/broken-async', async (req, res) => {
  await new Promise(resolve => setTimeout(resolve, 1000));
  throw new Error('Broken async!');
});

这里的错误不会被Express的错误中间件捕获——因为async函数会把内部抛出的错误包装成Promise的reject状态,而Express默认不会自动处理Promise的reject,所以这个错误就“悄无声息”地丢失了,根本传不到你的全局错误中间件里。

两种靠谱的解决办法

1. 手动用try/catch捕获并传递错误

最简单的方式就是在异步路由里用try/catch包裹所有异步操作,把捕获到的错误传给next():

app.get('/broken-async', async (req, res, next) => {
  try {
    await new Promise(resolve => setTimeout(resolve, 1000));
    throw new Error('Broken async!');
  } catch (error) {
    next(error); // 把错误交给全局错误中间件处理
  }
});

这样错误就能被你的中间件正常捕获,返回500响应给客户端了。

2. 写一个通用的异步路由包装器

如果你的异步路由很多,每个都写try/catch太繁琐,可以写一个通用的包装函数,自动捕获async函数的错误并传给next():

// 通用异步路由处理器
const asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

// 使用方式
app.get('/broken-async', asyncHandler(async (req, res) => {
  await new Promise(resolve => setTimeout(resolve, 1000));
  throw new Error('Broken async!');
}));

这个包装器会自动把async函数返回的Promise的reject传递给next(),相当于帮你省去了重复写try/catch的工作,用起来非常省心。

内容的提问来源于stack exchange,提问作者sdgfsdh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:49:36