全局异常处理

面向切面编程

异常处理分为:

已知错误:前端请求数据类型校验错误等
未知错误:代码语法错误、环境报错等


已知错误:
在models层引入下面声明好的异常报错类,根据业务需求,抛出指定错误类,然后全局进行异常拦截处理,并返回客户端

201: 查询成功
200: 提交成功
403:禁止访问
参考:参见数字代码设置响应状态
声明好的异常报错类:

  • 声明的异常报错类继承于Error
class HttpException extends Error{
    constructor(msg='服务器异常',errorCode=10000, code=400){
        super()
        this.errorCode = errorCode
        this.code = code
        this.msg = msg
    }
}

class Success extends HttpException{
    constructor(msg, errorCode){
        super()
        this.code = 201
        this.msg = msg || 'ok'
        this.errorCode = errorCode || 0
    }
}

class AuthFailed  extends HttpException {
    constructor(msg, errorCode) {
        super()
        this.msg = msg || '授权失败'
        this.errorCode = errorCode || 10004
        this.code = 401
    }
}

客户端异常返回格式:

ctx.body = {
    msg:error.msg,
    error_code:error.errorCode,
    request:`${ctx.method} ${ctx.path}`
  }
ctx.status = error.code

models层引入声明好的异常报错类:

class User extends Model {
    static async verifyEmailPassword(email, plainPassword) {
        const user = await User.findOne({
            where: {
                email
            }
        })
        if (!user) {
            throw new global.errs.AuthFailed('账号不存在')
        }
        // user.password === plainPassword
        const correct = bcrypt.compareSync(
            plainPassword, user.password)
        if(!correct){
            throw new global.errs.AuthFailed('密码不正确')
        }
        return user
    }

    static async getUserByOpenid(openid){
        const user = await User.findOne({
            where:{
                openid
            }
        })
        return user
    }

    static async registerByOpenid(openid) {
        return await User.create({
            openid
        })
    }
}

全局异常处理拦截:(中间件 Middlewares

  • 这里的未知错误异常处理,需要根据开发环境还是生产环境进行区分;
  • 如果是开发环境且是未知异常则抛出到cmd端,这样能方便开发时,定位异常报错位置。
  • 如果是生产环境未知异常报错,则cmd端不抛出异常,只是在客户端返回一个status500,这样能保证代码继续执行,而不是影响网站的其它功能正常运行。
const {HttpException} = require('../core/http-exception')

const catchError = async (ctx, next)=>{
    try {
        await next()
    } catch (error) {
        // 开发环境
        // 生产环境
        // 开发环境 不是HttpException
        const isHttpException = error instanceof HttpException
        const isDev = global.config.environment === 'dev'
        
        if(isDev && !isHttpException){
            throw error
        }
        
        if(isHttpException){
            ctx.body = {
                msg:error.msg,
                error_code:error.errorCode,
                request:`${ctx.method} ${ctx.path}`
            }
            ctx.status = error.code
        }
        else{
            ctx.body = {
                msg: 'we made a mistake O(∩_∩)O~~',
                error_code: 999,
                request:`${ctx.method} ${ctx.path}`
            }
            ctx.status = 500
        }
    }
}

module.exports = catchError

注入全局异常处理:

app.use(catchError)

你可能感兴趣的:(全局异常处理)