Gin 实现统一异常处理和封装统一返回结果
创始人
2025-07-07 15:00:52
0

在使用Gin开发web应用的时候,业务异常是很常见的,通常我们会为每个异常情况定义一个唯一的error。同时当发生异常的时候,我们也需要把异常信息放入到接口的响应信息里面,方便页面上做提示。

//业务异常
package bizerr


const (
 // 定义可预见的异常
  UserNotFound = 10001
  PasswrodErr = 10002
)


var resultCodeText = map[int]string{
  UserNotFound: "用户不存在",
}


func Message(code int) (string, bool) {
  message, ok := resultCodeText[code]
  return message, ok
}

错误码这里有5位 

1

01

01

错误级别,如服务级

模块级,如用户模块

具体的错误码,如用户名错误

  • 错误级别:服务级错误用1,普通错误用2,通常是用户的非法操作      
  • 模块级错误码:2 位数进行表示,比如 01 为用户模块;02 为订单模块  
  • 具体错误码:2 位数进行表示,比如 01 为手机号不合法;02 为密码输入错误

为了让这些错误信息以及正常情况的返回数据都有统一的结构来管理,我们需要先定义一个统一返回的数据结构体。

要想实现统一的异常处理,我们需要借助Gin提供的中间件功能去在返回数据之前,拦截到出现的错误,在这里重新包装成我们定义的统一结构体。

package middleware


import (
  "net/http"


  "github.com/gin-gonic/gin"
)


// Result 表示统一响应的JSON格式
type Result struct {
  Code    int         `json:"code"`    // 状态码
  Message string      `json:"message"` // 响应消息
  Data    interface{} `json:"data"`    // 响应数据
}

接下来我们要给 Result 提供几个常用的方法,比如出现异常时候需要调用的方法,正常情况下需要调用的方法。

func Fail(c *gin.Context, code int, message string) {
  c.JSON(code, Result{
    Code:    code,
    Message: message,
    Data:    nil,
  })
   c.Abort()
}
  //异常信息从定义好的bizerr里面获取
 func Fail(c *gin.Context, code int) {
  message, _ := bizerr.StatusText(code)
  c.JSON(code, Result{
    Code:    code,
    Message: message,
    Data:    nil,
  })
  c.Abort()
}


//ok  不需要返回数据 data
func Ok(c *gin.Context, code int) {
  c.JSON(code, Result{
    Code:    code,
    Message: message,
    Data:    nil,
  })
}


//接口执行正常 需要返回数据 data
func Ok(c *gin.Context, code int, message string,
 data interface{} ) {
  c.JSON(code, Result{
    Code:    code,
    Message: message,
    Data:    data,
  })
}


//接口执行正常 需要返回数据 data
func Ok(c *gin.Context, code int,
 data interface{} )
 {
  c.JSON(code, Result{
    Code:    code,
    Message: "ok",
    Data:    data,
  })
}

实现拦截返回结果的中间件

func GlobalErrorMiddleware() gin.HandlerFunc {
  return func(c *gin.Context) {
  
   //先执行请求
    c.Next()


    // 发生了错误
    if len(c.Errors) > 0 {
    //获取最后一个error 返回
      err := c.Errors.Last()
      Fail(c, http.StatusInternalServerError, err.Error())
      return
    }


    
    
  }
}

使用中间件

func main() {
  r := gin.New()
  r.Use(middleware.GlobalErrorMiddleware())


  r.GET("/test2", func(c *gin.Context) {
    m := map[string]interface{}{
      "lang": "go",
       
     } 
    data:=Result{
     Data: m,
    }
    
    middleawre.Ok(http.Status.OK,data)
  })
  
  r.Run(":8080")
}

使用postman 返回

图片图片

由此,我们看到了Gin提供的中间件的威力,中间件可以帮助我们做很多中间的事情。

通过定义统一的返回结构,使得我们的所有接口都可以以相同的数据结构展示给需要调用接口的人。大大提高了代码的可读性和维护性。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
P2P的自白|我不生产内容,我... 现在一提起P2P,人们就会联想到正在被有关部门“围剿”的互联网理财服务。×租宝事件使得劳...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...