Golang Gin 全局错误处理
前言
本文主要介绍Golang Gin
框架中全局处理错误的方法,水一下文章。
使用嵌套
就是在路由函数外面套层壳,侵入性大,不推荐这种处理方式。
type handle func(c *gin.Context) error
func errorHandle(f handle) func(c *gin.Context) {
return func(c *gin.Context) {
err := f(c)
if err != nil {
c.JSON(http.StatusInternalServerError, err.Error())
}
}
}
使用:
// 套在原路由函数,有多少个套多少次
router.GET("/b", errorHandle(func(c *gin.Context) error {
return fmt.Errorf("1145141919810")
}))
使用panic
与recover
Gin
带有一个gin.Recovery
中间件,用于捕获panic
,说明我们可以通过中间件的方式捕获错误,而且panic
与recover
是原生的,非常方便,但只能捕获同一协程下的错误。
自定义错误接口:
package custom
var ErrorMessage map[int]string
type RequestError struct {
Code int `json:"code"`
Message string `json:"message"`
Stack string `json:"stack,omitempty"`
}
func (err *RequestError) Error() string {
return err.Message
}
func NewRequestError(code int, err ...error) *RequestError {
e := new(RequestError)
e.Code = code
if v, ok := ErrorMessage[code]; ok == true {
e.Message = v
} else {
e.Message = "server error"
}
// runtime.Stack()
if len(err) >= 1 {
for i := range err {
e.Stack += err[i].Error()
e.Stack += "\n"
}
}
return e
}
func init() {
ErrorMessage = make(map[int]string)
// 以此类推定义错误信息
ErrorMessage[401] = "Unauthorized"
}
自定义中间件:
package custom
import (
"github.com/gin-gonic/gin"
"net/http"
)
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if err := recover(); err != nil {
// 类型断言,因为 panic 是个 any ,什么都可以丢
if v, ok := err.(*RequestError); ok == true {
c.JSON(v.Code, v)
} else {
c.String(http.StatusInternalServerError, "Internal Server Error")
}
c.Abort()
}
}()
// 传递下一棒
c.Next()
}
}
使用:
router.Use(custom.ErrorHandler())
router.GET("/a", func(c *gin.Context) {
// 抛个错误
panic(custom.NewRequestError(401))
c.String(http.StatusOK, "hello")
})