## 4.1 500错误
> 如果代码运行过程中发生错误,我们需要把错误信息返回给用户。HTTP 协定约定这时要返回500状态码。Koa 提供了ctx.throw()方法,用来抛出错误,ctx.throw(500)就是抛出500错误
- 关键词:ctx.throw(500)
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
const main = (ctx, next) => {
ctx.throw(500)
}
app.use(main)
app.listen(3000)
# 访问
internal server error
```
## 4.2 404错误
> 如果将ctx.response.status设置成404,就相当于ctx.throw(404),返回404错误。
- 关键词:ctx.response.status=404
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
const main = (ctx, next) => {
ctx.response.status = 404;
ctx.response.body='Page not Found'
}
app.use(main)
app.listen(3000)
```
## 4.3 处理错误的中间件
> 为了方便处理错误,最好使用try...catch将其捕获。但是,为每个中间件都写try...catch太麻烦,我们可以让最外层的中间件,负责所有中间件的错误处理。
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
const errorHandler = async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.response.status = err.statusCode || err.status || 500
ctx.response.body = {
msg:err.message
}
}
}
const main = ctx => {
ctx.response.status = 200
}
app.use(errorHandler)
app.use(main)
app.listen(3000)
```
## 4.4 error事件的监听
> 运行过程中一旦出错,Koa 会触发一个error事件。监听这个事件,也可以处理错误。
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
app.on('error', (err, next) => {
console.error('server error',err)
})
const main = ctx => {
ctx.throw(500)
}
app.use(main)
app.listen(3000)
```
## 4.5 释放error事件
> 需要注意的是,如果错误被try...catch捕获,就不会触发error事件。这时,必须调用ctx.app.emit(),手动释放error事件,才能让监听函数生效。
- 关键字:ctx.app.emit('error')触发事件
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
const handler = async ctx => {
try {
await next()
} catch (err) {
ctx.response.status = err.statusCode || err.status || 500
ctx.response.type='html'
ctx.response.body='<h1>发生了一个错误</h1>'
// 当不写这行时,发生错误时,命令行里看不到错误消息
ctx.app.emit('error',err,ctx)
}
}
const main = ctx => {
ctx.throw(500)
}
app.on('error', err=> {
console.error('server error',err.message)
console.log(err)
})
app.use(handler)
app.use(main)
app.listen(3000)
```