Express.js自定义错误中间件失效:/users路由异常未被捕获
问题原因分析
async函数的错误不会被Express自动捕获(Express 4及以下)
Express 4及更早版本的路由处理逻辑,不会自动处理async函数抛出的错误。因为async函数里的错误会被包装成Promise的reject状态,而Express默认不会等待这个Promise完成,也就无法捕获到这个reject,自然不会把错误传递给你的errorMiddleware。非async路由的处理逻辑不同
你测试的/error、/unhandled-error路由,如果是同步抛出错误(非async函数),Express会直接捕获并传递给错误中间件;如果是async函数但手动用try/catch捕获了错误,并调用next(err)把错误传递出去,也能正常触发中间件。但/users/:user_id的async路由显然没做这个处理。路由代码存在疏漏
检查你的/users/:user_id路由处理函数,大概率是没把async函数的错误接入Express的错误处理流程:要么没给异步逻辑加try/catch,要么catch块里没调用next(err)抛出错误。比如错误的写法:app.get('/users/:user_id', async (req, res) => { // 异步操作,比如查库 if (!user) { throw new CustomException('用户不存在'); // 这个reject不会被Express捕获 } res.send(user); });正确的写法应该手动捕获错误并传递给next:
app.get('/users/:user_id', async (req, res, next) => { try { // 异步操作 if (!user) { throw new CustomException('用户不存在'); } res.send(user); } catch (err) { next(err); // 关键:把错误交给Express的错误中间件处理 } });Express版本差异(可选)
如果你用的是Express 5,它会自动处理async函数的错误,把Promise的reject自动转换成错误传递给中间件,但Express 4及以下没有这个特性,这也可能是你遇到差异的原因。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

