koa2 默认的处理

koa2 简单易用,代码量少且易读,代码实现中有大量“经验法则”,了解这些才能用好它。

默认的响应处理

  • req.statusCode 默认值为 404
  • response.body 赋值时

    如果赋 null 值,将 response.status 置为 204

    如果之前没有通过为 response.status 赋值的方式设置状态码,则将 response.status 置为 200

    如果之前没有设置 content-type 头,则根据值的内容推算出 content-type (默认为 json ),

    如:内容是 string 类型,以 < 开头则认为是 html 否则是 text

  • 响应码为 204、205、304 时强制 response.body 为空

默认的异常处理

koa2 在中间件的最外层会捕获异常,将它转化为合适的 HTTP 错误响应:

  • app 发送 error 事件,而 app 的处理则是输出日志到控制台
  • 如果 HTTP 响应头已经发送,则不走下面的流程,不做任何处理
  • 清空 HTTP 响应头
  • 设置响应头为 err.headers
  • err.codeENOENT 时设置 err.status404
  • err.status 为无效的 HTTP 状态码时修复为 500
  • err.status 做为 HTTP 状态码
  • err.expose 为真时使用 err.message 做为 HTTP 响应体,否则使用 err.status 对应的文本描述做为 HTTP 响应体

自定义异常处理

  • 自定义日志输出

    如:使用 bunyan 来输出日志

    app.on('error', function(err, ctx) {
        logger.error({
            stack: err.stack,
            ctx: ctx
        }, "service error");
    });
    
  • 自定义异常响应

    如:总是响应 json ,格式为 { message: "错误描述" }

    app.use(async (ctx, next) => {
        try {
            await next();
        } catch ( err ) {
            ctx.app.emit('error', err, ctx);
            ctx.status = err.status || 500;
            ctx.body = {
                message: err.expose ? err.message : ctx.message
            };
            return;
        }
    
        if (ctx.status == 404) {
            if (!ctx.body || !ctx.body.message) {
                // explicitly set status, avoid revert to 200 when assign body.
                ctx.status = 404;
                ctx.body = {
                    message: ctx.message
                };
            }
        }
    })
    

node