在开发中,为了及时的反馈信息,与前端对接好,异常处理,是后端必须去做的一种事情,反馈正确的信息,可以加快bug的解决
在
node
中,由于基本都是异步方法,所以,为了能够处理好异步的异常,我们需要使用async/await
来解决
一、异常处理Demo
-
由于中间件的特性,使得它可以用来作为全局异常处理的一个好途径
-
为了代码的分离性,我们可以新建一个 专门存放中间件的文件夹
middlewares
,然后新建一个文件exception.js
,用来存放异常处理的代码 -
exception.js
const catchError = async (ctx, next) => {
try {
await next()
} catch (error) {
ctx.body = '服务器错误'
}
}
module.exports = catchError
- 主文件引入
app.js
// 引入并注册全局异常处理
// 注意:要放在代码前面,路由注册前面
const catchError = require('./middlewares/exception')
app.use(catchError)
现在在路由文件抛出一个异常试试
throw new Error('API Exception')
使用posman发出请求试试
返回了一个错误信息
二、定义异常类并运用
在后端编程中,面向对象的思想尤为重要,node也是如此,我们不妨将我们需要捕获到的异常编成一个个的异常类,需要的时候就抛出这个异常类,便更加的方便了
2.1、异常类的基类(父类)
首先,我们可以编写一个基类,来作为后面其他异常类的 父类,其他都可以基于这个类来延展开来
http-exception.js
/**
* http 错误类型的 对象
*/
class HttpException extends Error {
/**
* 构造函数,可以设置默认值
* @param {返回的错误信息} msg
* @param {错误编号} errorCode
* @param {httpcode} code
*/
constructor(msg='服务器异常', errorCode=10000, code=400) {
super()
this.errorCode = errorCode
this.code = code
this.msg = msg
}
}
module.exports = HttpException
2.2、简单使用一个这个异常类
找一个路由,设置你想要的一个参数,为它设置规范,如果传来的参数不符合这个规范,那么就会报错
classic.js
const Router = require('koa-router')
const router = new Router()
// 导入这个异常类
const HttpException = require('../../../core/http-exception')
router.post('/v1/:id/classic/latest', async ctx => {
const id = ctx.request.body.id
// 如果这个参数没有传入,那么会报错
if(id) {
const error = new HttpException('错误信息', 10001, 400)
throw error
}
ctx.body = {key: 'calssic'}
})
// 3. 导出路由
module.exports = router
然后修改上面定义过的,处理异常的中间件``exception.js`
// 导入这个异常类
const HttpException = require('../core/http-exception')
const catchError = async (ctx, next) => {
// 尝试拦截错误
try {
await next()
} catch (error) {
// 判断是否是定义过的错误类型
if(error instanceof HttpException) {
ctx.body = {
msg: error.msg,
error_code: error.errorCode,
request:`${ctx.method} ${ctx.path}`
}
ctx.status = error.code
}
}
}
module.exports = catchError
返回信息
三、定义异常类的子类
3.1、定义参数
我们可以在这个异常类的基类延展开来,定义各种不同异常类的子类
例如:
- 参数错误
- 路径错误
- 禁止访问
- 未授权
- 未找到资源
- 等等
参数错误:ParameterException
/**
* 参数错误 的异常类
*/
class ParameterException extends HttpException {
constructor(msg, errorCode) {
super()
this.code = 400
this.msg = msg || '参数错误'
this.errorCode = errorCode || 10000
}
}
module.exports = {
HttpException,
ParameterException
}
3.2、改写上面的Demo
在路由里面,我们将父类HttpException
改为子类ParameterException
router.post('/v1/:id/classic/latest', async ctx => {
const id = ctx.request.body.id
// 如果这个参数没有传入,那么会报错
if(id) {
const error = new ParameterException('参数未传递', 10001)
throw error
}
ctx.body = {key: 'calssic'}
})
效果也是一样的