基於Gin框架實現異常處理

Darius_zh發表於2021-07-12

記錄一下如何利用recovergin中介軟體來優雅的實現異常處理

首先是中介軟體的實現:

package exception

import (
    "github.com/gin-gonic/gin"
    "log"
    "net/http"
)

type Api struct {
    Code    int
    Message string
}

// Handler 異常處理
func Handler(c *gin.Context) {
    defer func() {
        if r := recover(); r != nil {
            switch t := r.(type) {
            case *Api:
                log.Printf("panic: %v\n", t.Message)
                c.JSON(t.Code, gin.H{
                    "message": t.Message,
                })
            default:
                log.Printf("panic: internal error")
                c.JSON(http.StatusInternalServerError, gin.H{
                    "message": "伺服器內部異常",
                })
            }
            c.Abort()
        }
    }()

    c.Next()
}

在路由初始化後緊接著加入該中介軟體:

router = gin.Default()
router.Use(exception.Handler)

使用案例,如在處理資料庫異常時:

func (appUser *AppUser) Create() {
    if err := db.DB.Create(&appUser).Error; err != nil {
        //  資料庫寫入失敗
        panic(&exception.Api{Code: http.StatusInternalServerError, Message: err.Error()})
    }
}

又或者是在業務邏輯中:

//  賬號密碼校驗
if hasRecord && bcrypt.CompareHashAndPassword(appUser.Password, inputPassword) != nil {
    panic(&exception.Api{Code: http.StatusUnauthorized, Message: "密碼錯誤"})
}

通過這種方式可以減少大量判斷errif else的邏輯,非常好用

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章