優雅 | koa處理異常

一個良好的編碼習慣必然離不開異常處理,本文將會介紹如何在koa框架下面如何拋出錯誤,並統一處理返回異常。web

正常錯誤處理

koa是一個優秀的NodeJs web框架,在咱們開發web項目的時候,避免不了任何錯誤處理,包括http錯誤以及自定義的業務邏輯處理。
在Node.js 中,拋出錯誤以下服務器

if(someCondition){
    throw Error("Error");
}

Http錯誤處理

這裏使用ctx.throw(400)的方式,拋出http錯誤,同時返回一些信息。微信

ctx.status = 400
ctx.body = {
    msg: "some params is invalid"
}

此時既返回了狀態碼,又返回了相關的錯誤信息。app

業務邏輯錯誤處理

若是須要開發Restful API server,這個時候須要定義若干的業務邏輯錯誤代碼,像下面這樣的框架

code碼 說明
0 success
-1 server error
4001 token 過時

這個時候,就須要在業務層中進行處理。koa

router.get("/", (ctx, next) => {
    if(tokenExpire(token)){
        const errcode = ERROR_CODE.TOKEN_EXPIRED;
        ctx.body = {
            errcode,
            msg: ERROR_MSG[errcode]
        }
        return
    }
})

這裏,就返回了相關的errcode,經過errcode的方式返回了相關的錯誤代碼async

全局捕獲異常處理

這裏在koa裏,全局捕獲異常,這裏使用中間件的方式,確保異常能夠捕獲到
在middlewares創建一個catcherror中間件,達到捕獲到異常的方式ui

// middlewares/catcherror.js
const catchError = async(ctx, next) => {
    try{
        await next();
    }catch(error){
        if(error.errorCode){
            console.log("捕獲到異常")
            return ctx.body = errror.msg;
        }
    }
}
module.exports = catchError

這樣定義一箇中間件,在中間件進行相關的捕獲,確保捕獲到相關的異常,並把這個中間件進行導出。this

放在next裏面,若是next程序出現異常,就能夠實如今中間件進行相關的捕獲。編碼

const koa = require("koa")
const Router = require("router")
const app = new koa();
const router = new Router();
const catchError = require("./middlewares/catcherror")

app.use(catchError)

router.get('/login', (ctx, next) => {
    const path = ctx.request.query;
    
    // 主動拋出錯誤
    if(true){
        const error = new Error();
        error.errorCode = 1000;
        error.msg = "錯誤";
        throw error
    }
})

app.use(router.routers())
app.listen(3000)

這個時候,憑藉着中間件,能夠實現拋出錯誤異常。

使用基類的方式處理

主動拋出錯誤,會顯示的至關麻煩,這裏使用面向對象的方式,繼承error類。
把錯誤信息,放入到error類中,經過放入error類中,實現對錯誤的直接拋出。

// core/http-exception.js

class HttpException extends Error{
    constructor(msg = '服務器異常', errorCode = 1000. code = 400){
        super();
        this.msg = msg;
        this.code = code;
        this.errorCode = errorCode;
    }
}
module.export = HttpException

再次改寫app.js

// app.js
const koa = require('koa')
const Router = require('router')
const app = new koa()
const router = new Router()
const {HttpException} = require('../core/http-exception')
const catchError = require('./middlewares/catcherror')

app.use(catchError) //必定要放在第一個中間件

router.get('/login',(ctx,next)=>{
    const path = ctx.request.query
    
    // 咱們主動拋出一個錯誤
    if(true){
        // 主要改寫這裏,建立新的異常
        const error = new HttpException('登陸錯誤',10000,500)
        throw error
    }
})

app.use(router.routes())
app.listen(3000)

再次改寫中間件,判斷異常是否屬於此異常的對象

// middlewares/catcherror.js
const {HttpException} = require('../core/http-exception')
const catchEoore = async (ctx,next)=>{
        try{
            await next()
        } catch(error){
            if(error instanceof HttpExcetion){
                return ctx.body = error.msg
            }
        }
    }
}

module.exports = catchError

這樣就完成了一次的改寫。

微信公衆號

相關文章
相關標籤/搜索