基于Gin框架实现异常处理

记录一下如何利用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 协议》,转载必须注明作者和本文链接
讨论数量: 1

子协程 Panic 怎么处理?而且我理解你这个例子会导致滥用Panic?

2年前 评论
_Ten (楼主) 2年前
d_1_111 (作者) 2年前
d_1_111 (作者) 2年前
d_1_111 (作者) 2年前
_Ten (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!