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放入到一个先进后出的队列中
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
