5-1 错误处理简介
什么是错误处理
- 编程语言或计算机硬件里的一种机制
- 处理软件或信息系统中出现的异常状况
异常状况由哪些?
- 运行时错误,都返回 500
- 逻辑错误,如找不到(404)、先决条件失败(401)、无法处理的实体(参数格式不对,422)等
为什么要用错误处理?
- 防止程序挂掉
- 告诉用户错误信息
- 便于开发者调试
5-2 koa 自带的错误处理
404
412
findById (ctx) {
if (ctx.params.id * 1 >= db.length) {
ctx.throw(412, '先决条件失败:id 大于等于数组长度了')
}
ctx.body = db[ctx.params.id * 1]
}
500
find (ctx) {
a.b // 手动制造运行时错误
ctx.body = db
}
5-3 手动编写错误处理中间件
const koa = require('koa')
const bodyparser = require('koa-bodyparser')
const app = new koa()
const routing = require('./routes')
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = err.status || err.statusCode || 500
ctx.body = {
message: err.message
}
}
})
app.use(bodyparser())
routing(app)
app.listen(3000, () => console.log('程序启动在 3000 端口了'))
中间的err.status 或 err.statusCode 即是错误码了,复用之前手动抛出的412错误,如图所示:
5-4 使用 koa-json-error 进行错误处理
- 安装 koa-json-error
- 使用 koa-json-error的默认配置处理错误
- 修改配置使其在生产环境下禁用错误堆栈的返回
npm i koa-json-error --save
app/index.js
const koa = require('koa')
const bodyparser = require('koa-bodyparser')
const error = require('koa-json-error')
const app = new koa()
const routing = require('./routes')
app.use(error())
app.use(bodyparser())
routing(app)
app.listen(3000, () => console.log('程序启动在 3000 端口了'))
404错误
412错误
500错误
然而有一个不满意,就是在客户端可以获取到堆栈信息,这是不安全的,不可用于生产阶段。
修改配置适用于生产阶段(即去掉 stack 字段)
- 安装跨平台环境设置环境变量
npm i cross-env --save-dev
2.package.json
"scripts": {
"start": "cross-env NODE_ENV=production nodemon app",
"dev": "nodemon app"
}
- index.js配置
app.use(error({
postFormat: (e,{stack, ...rest}) =>process.env.NODE_ENV === 'production' ? rest: {stack, ...rest}
}))
通过es6的解构,如果是生产环境的话去掉stack。
4.验证
npm start:
npm run dev:
5-5 适用 koa-parameter 校验参数
可以手动适用js代码校验客户端传过来的参数,不过太麻烦且不优雅。npm i koa-parameter --save
const koa = require('koa')
const bodyparser = require('koa-bodyparser')
const error = require('koa-json-error')
const parameter = require('koa-parameter')
const app = new koa()
const routing = require('./routes')
app.use(error({
postFormat: (e,{stack, ...rest}) =>process.env.NODE_ENV === 'production' ? rest: {stack, ...rest}
}))
app.use(bodyparser())
app.use(parameter(app))
routing(app)
app.listen(3000, () => console.log('程序启动在 3000 端口了'))
const parameter = require(‘koa-parameter’)
app.use(parameter(app))
使用:
controller/users.js
create (ctx) {
ctx.verifyParams({
name: {type: 'string', required: true},
age: {type: 'number', required: false}
})
db.push(ctx.request.body)
ctx.body = ctx.request.body
}