全书目录

第三十六篇:Koa 完全指南 —— 洋葱关卡巡防宇宙

第六章:错误处理 —— 最外层总控室才是事故回收中心

1 分钟 342 字 第 689 / 962 个阅读单元

Koa 的错误处理,和它的洋葱模型是强绑定的。

最稳的姿势通常是:

  • 最外层用一个 try/catch 中间件兜底
  • 业务里用 ctx.throw() / ctx.assert()
  • 再配合 app.on('error') 统一记日志

这是 Koa 项目最常见、也最成熟的写法。

js
import Koa from 'koa'

const app = new Koa()

app.use(async (ctx, next) => {
  try {
    await next()
  } catch (err) {
    ctx.status = err.status || 500
    ctx.body = {
      message: err.expose ? err.message : '巡防塔内部故障',
    }
    ctx.app.emit('error', err, ctx)
  }
})

app.use(async (ctx) => {
  ctx.throw(403, '你没有进入核心舱的权限')
})

app.on('error', (err, ctx) => {
  console.error('server error', {
    message: err.message,
    path: ctx.path,
    method: ctx.method,
  })
})

app.listen(3000)

这套机制的心智非常清楚:

text
内层关卡发现事故
   │
   ▼
throw err / ctx.throw(...)
   │
   ▼
最外层总控室 catch 住
   │
   ├── 给客户端一个统一回执
   └── 发 error 事件做日志记录

Koa 官方默认也有错误处理逻辑:

  • 没开启 app.silent 时会往 stderr 打错误
  • 还能在能响应时自动给 500
  • 同时会发出 app 级别 error 事件

但工程里你几乎都会自己接一层错误中间件,因为你需要:

  • 统一 JSON 结构
  • 统一错误码
  • 统一日志格式
  • 统一 trace id
  • 控制哪些错误信息能暴露给客户端

一句话记住:

业务关卡负责发现事故,最外层负责回收事故。