全部学科
Python全栈
python
NodeJS全栈
nodejs
📅 2026-05-18 6 分钟 ✍️ juanwangdev

错误处理

参数绑定中的错误处理是构建健壮 API 的关键环节。

绑定错误类型

Gin 的绑定方法返回不同类型的错误:

Go
type User struct {
    Name string `json:"name" binding:"required"`
    Age  int    `json:"age" binding:"gte=0"`
}

r.POST("/user", func(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        // 判断错误类型
        switch err.(type) {
        case validator.ValidationErrors:
            // 校验错误
            c.JSON(400, gin.H{
                "code":    400,
                "message": "参数校验失败",
                "detail":  err.Error(),
            })
        case *json.UnmarshalTypeError:
            // JSON 类型错误
            c.JSON(400, gin.H{
                "code":    400,
                "message": "JSON格式错误",
            })
        default:
            // 其他错误
            c.JSON(400, gin.H{
                "code":    400,
                "message": "请求解析失败",
            })
        }
        return
    }
    c.JSON(200, user)
})

MustBind vs ShouldBind

方法错误处理方式返回状态码
MustBind自动返回 400,终止请求400
ShouldBind返回错误,自行处理自定义
Go
// MustBind: 错误时自动返回 400
r.POST("/must", func(c *gin.Context) {
    var user User
    c.MustBindJSON(&user) // 失败自动终止
    c.JSON(200, user)
})

// ShouldBind: 需要手动处理错误
r.POST("/should", func(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    c.JSON(200, user)
})

统一错误处理函数

Go
// 统一错误响应
func BindError(c *gin.Context, err error) {
    var message string

    if validationErrors, ok := err.(validator.ValidationErrors); ok {
        // 处理校验错误
        for _, fieldErr := range validationErrors {
            message += fmt.Sprintf("字段 %s 校验失败: %s; ",
                fieldErr.Field(), fieldErr.Tag())
        }
    } else {
        message = "请求参数格式错误"
    }

    c.JSON(http.StatusBadRequest, gin.H{
        "code":    400,
        "message": message,
    })
}

// 使用示例
r.POST("/create", func(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        BindError(c, err)
        return
    }
    c.JSON(200, gin.H{"message": "创建成功"})
})

获取单个错误详情

Go
import "github.com/go-playground/validator/v10"

func FormatError(err error) string {
    if validationErrors, ok := err.(validator.ValidationErrors); ok {
        if len(validationErrors) > 0 {
            fe := validationErrors[0]
            return fmt.Sprintf("字段 %s 不满足 %s 规则",
                fe.Field(), fe.Tag())
        }
    }
    return err.Error()
}

r.POST("/item", func(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(400, gin.H{"error": FormatError(err)})
        return
    }
    c.JSON(200, user)
})

推荐使用 ShouldBind 系列,可以自定义错误响应格式和状态码。

要点总结

  • ShouldBind 返回错误需手动处理,更灵活
  • 校验错误类型为 validator.ValidationErrors
  • 统一错误处理函数可简化代码
  • 错误消息要清晰,便于前端调试
想在手机上练习这篇文章的配套题目?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一篇 参数校验
下一篇 → 基础路由配置
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码