gin定义统一处理错误

在gin中如果有错误需要响应给客户端,如果每一个都判断,并且处理返回,如果项目复杂了,需要写很多重复的代码来响应错误,今天我们来封装一个统一处理错误包装器,使用的是装饰器模式。

1.定义统一处理错误

pkg/e/error.go

package e

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

//自定义api错误结构体
type ApiError struct {
    Status int `json:"-"`
    Code int `json:"code"`
    Message string `json:"message"`
}

func (err ApiError)Error() string {
    return err.Message
}

2.编写统一错误处理函数

pkg/e/error_wrapper.go

package e

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

type WrapperHandle func(c *gin.Context) (interface{}, error)

func ErrorWrapper(handle WrapperHandle) gin.HandlerFunc {
    return func(c *gin.Context) {
        data, err := handle(c)
        if err != nil {
            apiError := err.(ApiError)
            c.JSON(apiError.Status, apiError)
            return
        }
        c.JSON(http.StatusOK, gin.H{"data": data})
    }
}
这里的统一处理只是一个简单的处理,介绍一种思路,具体的可以根据项目进行改造

3.例子

  • 编写控制器

api/err_handle.go

package api

import (
    "cn.sockstack/gin_demo/pkg/e"
    "github.com/gin-gonic/gin"
    "net/http"
)

func ErrorHandle(c *gin.Context) (interface{}, error) {
    query := c.Query("q")
    if query == "" {
        return nil, e.ApiError{
            Status:  http.StatusOK, //状态码
            Code:    404,
            Message: "q的参数不能为空",
        }
    }
    if query == "test" {
        return nil, e.ApiError{
            Status:  http.StatusOK, //状态码
            Code:    404,
            Message: "q的参数不能为test",
        }
    }

    return query, nil
}
  • 注册路由

routers/test.go

package routers

import (
    "cn.sockstack/gin_demo/api"
    "cn.sockstack/gin_demo/pkg/e"
    "github.com/gin-gonic/gin"
)

func test(r *gin.Engine)  {
    //定义/test路由
    r.GET("/test", api.Test)

    //响应json数据
    r.GET("/json", api.Json)
    //响应xml数据
    r.GET("/xml", api.Xml)
    
    
    //统一错误处理测试
    r.GET("/error", e.ErrorWrapper(api.ErrorHandle))
}
  • 运行并访问127.0.0.1:8081/error?q=hello
{
    "data": "hello"
}

正常响应结果

  • 运行并访问127.0.0.1:8081/error?q=test
{
    "code": 404,
    "message": "q的参数不能为test"
}
  • 运行并访问127.0.0.1:8081/error
{
    "code": 404,
    "message": "q的参数不能为空"
}

可以看到,两次访问都能处理错误结果,并以json返回,在业务开发中,只要返回自定义的ApiError错误,即可以统一格式返回错误。

这一节介绍的统一错误处理的灵感来源于gin的中间件。

潇尘渊
77 声望19 粉丝

会点php,java,go的菜鸡程序猿