1.定义Recover中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package handler import ( "awesomeProject/Result" "github.com/gin-gonic/gin" "log" "net/http" "runtime/debug" ) func Recover(c *gin.Context) { defer func() { if r := recover(); r != nil { //打印错误堆栈信息 log.Printf("panic: %v\n", r) debug.PrintStack() //封装通用json返回 //c.JSON(http.StatusOK, Result.Fail(errorToString(r))) //Result.Fail不是本例的重点,因此用下面代码代替 c.JSON(http.StatusOK, gin.H{ "code": "1", "msg": errorToString(r), "data": nil, }) //终止后续接口调用,不加的话recover到异常后,还会继续执行接口里后续代码 c.Abort() } }() //加载完 defer recover,继续后续接口调用 c.Next() } // recover错误,转string func errorToString(r interface{}) string { switch v := r.(type) { case error: return v.Error() default: return r.(string) } } |
2.使用Recover中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | func main() { router := gin.Default() //注意 Recover 要尽量放在第一个被加载 //如不是的话,在recover前的中间件或路由,将不能被拦截到 //程序的原理是: //1.请求进来,执行recover //2.程序异常,抛出panic //3.panic被 recover捕获,返回异常信息,并终止程序 router.Use(handler.Recover) router.GET("/ping", func(c *gin.Context) { // 无意抛出 panic var slice = []int{1, 2, 3, 4, 5} slice[6] = 6 }) router.Run(":8080") // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") } |