基于Gin框架实现异常处理

Golang
624
0
0
2022-05-17

记录一下如何利用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的逻辑,非常好用