【面经/八股】koa 错误处理机制

25 阅读2分钟

在前端面试中,koa也是一个经典的会被经常提到的点,这篇博客来总结一下koa的错误处理机制

koa 抛出错误的方式

直接 throw

在应用中直接使用throw抛出一个错误,这个不必多说

使用 koa.throw()

你可以使用koa.throw来指定错误的信息和status code,它与直接throw的区别就是它会在抛出的Error对象上挂载一些额外信息,官方文档是这样描述的:

image.png

在这个例子中,使用了ctx来指定status code400,若不指定,直接抛出一个错误的话,默认为500;同时还指定了一个expose属性,当exposetrue时,Error对象的message可以作为ctx.body--也就是响应体,返回给前端,当没有这个属性时,默认就是koa自己准备的一个message

感觉这里要修正一下,本人实测这个expose属性并没有什么用,还是要手动指定ctx.body才可以设置响应体,它是不会自动设置的,英文官网的描述如下:

image.png

koa 的错误处理方式

默认错误处理

这种方式的实现原理就是在所有中间件前再多加一个中间件,专门用于捕获其他中间件抛出的错误

app.use(async (ctx, next) => {
  try {
    await next();
  }
  catch(err) {
    ctx.status = err.status || 500;
    ctx.expose = true;
    ctx.body = {
      msg: err.message,
    }
  }
})

这样就可以在错误中间件中设置ctx的响应信息,返回给前端;详见koa官方文档中的描述:

image.png

这里有一个值得注意的地方是我用红色框起来的描述,在上面讲错误抛出方式的时候就已经讲过了

定义错误事件

可以使用错误事件来监听中间件的错误

app.on("error", (err, ctx) => {
  console.log("Error occured:", err);
})

但是要注意,如果已经有了默认错误处理程序的话,那么错误已经在默认的错误中间件中消化(catch)掉了,所以它是不会走到错误事件的回调中的,需要你自己手动在默认错误处理程序中手动触发

app.use(async (ctx, next) => {
  try {
    await next();
  }
  catch(err) {
    ctx.status = err.status || 500;
    ctx.body = {
      msg: err.message,
    }
    // 手动触发错误事件
    ctx.app.emit("error", err, ctx);
  }
})

然后你可以在错误事件回调中自行再去处理ctx中的响应信息

app.on("error", (err, ctx) => {
  // 修改响应体
  ctx.body = {
    msg: "错误事件",
  }
  console.log("Error occured:", err);
})