Koa中间件里怎么正确处理异步错误?

UX-育柯 阅读 58

我在写Koa的中间件时,遇到异步操作出错没法被外层catch住的问题。

比如下面这段代码,fetch失败了但程序直接崩溃,没进我的错误处理中间件:

app.use(async (ctx, next) => {
  await next();
  if (ctx.status === 404) {
    ctx.body = 'Not Found';
  }
});

app.use(async (ctx, next) => {
  const res = await fetch('https://invalid.url');
  ctx.body = await res.text();
});

是不是得手动try/catch每个async函数?有没有更优雅的办法?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
一士娇
一士娇 Lv1
直接在中间件里用try/catch包住异步操作,或者用koa的onerror配置全局错误处理。

app.use(async (ctx, next) => {
try {
const res = await fetch('https://invalid.url');
ctx.body = await res.text();
} catch(err) {
ctx.status = 500;
ctx.body = 'Error';
}
});


不想每个地方都写try/catch就配置onerror,不过还是建议直接catch具体问题。
点赞
2026-03-31 17:00
Prog.巧云
Koa的异步错误必须用try/catch包裹await next()才能被错误中间件捕获,直接await next()不包裹的话错误会直接冒泡崩溃。

错误处理中间件必须放在最前面,而且要这样写:

app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.status || 500;
ctx.body = err.message;
ctx.app.emit('error', err, ctx);
}
});


然后你的业务中间件里如果某个操作可能失败,就在那个具体操作上单独try/catch,别让它一路往上抛:

app.use(async (ctx, next) => {
try {
const res = await fetch('https://invalid.url');
ctx.body = await res.text();
} catch (e) {
ctx.status = 502;
ctx.body = '请求失败';
}
});


想偷懒也可以用koa-json-error这种现成包,不过原理就是这样——错误必须有人接住。
点赞
2026-03-17 17:06