記錄一下如何利用recover
和gin
中介軟體來優雅的實現異常處理
首先是中介軟體的實現:
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: "密碼錯誤"})
}
通過這種方式可以減少大量判斷err
做if else
的邏輯,非常好用
本作品採用《CC 協議》,轉載必須註明作者和本文連結