golang(gin)的全局统一异常处理方式,并统一返回json
作者:刘海琼宝宝
这篇文章主要介绍了golang(gin)的全局统一异常处理方式,并统一返回json,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
golang(gin)全局统一异常处理,并统一返回json
定义Recover中间件
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) } }
使用Recover中间件
func main() { router := gin.Default() //注意 Recover 要尽量放在第一个被加载 //如不是的话,在recover前的中间件或路由,将不能被拦截到 //程序的原理是: //1.请求进来,执行recover //2.程序异常,抛出panic //3.panic被 recover捕获,返回异常信息,并Abort,终止这次请求 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") }
golang中异常处理问题
程序在运行过程中如果出现了问题,可以通过抛出异常、捕获异常来进行异常的处理,在golang中,异常的接口为error:
type error interface { Error() string }
因此,只要一个结构体实现了Error() string方法,就是实现了error接口:
type MyError struct { } func (err *MyError)Error() string{ return "this is MyError" }
golang中可以通过panic来抛出异常,recover来捕获异常。如果不处理异常,最终会是程序整个退出
另外**捕获异常必须在defer中进行捕获,否则捕获异常recover不起作用**
type MyError struct { } func (err *MyError)Error() string{ return "this is MyError" } func PanicError() { fmt.Println("panic error") panic(MyError{}) } func main() { defer func(){ if err := recover() ; err != nil { fmt.Println("catch error ",err) } }() PanicError() }
defer的机制,有点类似于java中的finall语句块
go中多个defer语句与defer的顺序相反执行,可以理解是将defer放入到一个先进后出的队列中
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。