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.code
为ENOENT
时设置err.status
为404
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 }; } } })