全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 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
  • 统一错误处理函数可简化代码
  • 错误消息要清晰,便于前端调试

📝 发现内容有误?点击此处直接编辑

← 上一篇 请求参数绑定
下一篇 → RESTful风格API设计
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库