KOA --- 5. 全局异常处理

在开发中,为了及时的反馈信息,与前端对接好,异常处理,是后端必须去做的一种事情,反馈正确的信息,可以加快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发出请求试试

KOA --- 5. 全局异常处理_第1张图片

返回了一个错误信息

二、定义异常类并运用

在后端编程中,面向对象的思想尤为重要,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

返回信息
KOA --- 5. 全局异常处理_第2张图片

三、定义异常类的子类

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'}

})

效果也是一样的

你可能感兴趣的:(node)