【问题标题】:Gin Gonic Custom Error Message Fails When Invalid Data Sent发送无效数据时 Gin Gonic 自定义错误消息失败
【发布时间】:2021-09-28 20:08:11
【问题描述】:

验证器结构

type RegisterValidator struct {
    Name              string     `form:"name" json:"name" binding:"required,min=4,max=50"`
    Email             string     `form:"email" json:"email" binding:"required,email,min=4,max=50"`
    Password          string     `form:"password" json:"password" binding:"required,min=8,max=50"`
    MobileCountryCode int        `form:"mobile_country_code" json:"mobile_country_code" binding:"required,gte=2,lt=5"`
    Mobile            int        `form:"mobile" json:"mobile" binding:"required,gte=5,lt=15"`
    UserModel         users.User `json:"-"`
}

如下格式化自定义错误:

type CustomError struct {
    Errors map[string]interface{} `json:"errors"`
}

func NewValidatorError(err error) CustomError {
    res := CustomError{}
    res.Errors = make(map[string]interface{})
    errs := err.(validator.ValidationErrors)

    for _, v := range errs {
        param := v.Param()
        field := v.Field()
        tag := v.Tag()

        if param != "" {
            res.Errors[field] = fmt.Sprintf("{%v: %v}", tag, param)
        } else {
            res.Errors[field] = fmt.Sprintf("{key: %v}", tag)
        }
    }

    return res
}

在发送数据时工作

{
    "email": "me@example.com",
    "name": "John Doe",
    "mobile_country_code": 1,
    "mobile": 1234567
}

但发送的类型无效

{
    "email": "me@example.com",
    "name": "John Doe",
    "mobile_country_code": "1",
    "mobile": 1234567
}

抛出错误interface conversion: error is *json.UnmarshalTypeError, not validator.ValidationErrors

这个问题和这个有关:How to assert error type json.UnmarshalTypeError when caught by gin c.BindJSON 但是答案没有意义。

【问题讨论】:

    标签: validation go go-gin


    【解决方案1】:

    正如异常所暗示的,以下行类型转换失败

        errs := err.(validator.ValidationErrors)
    

    必须将不同类型的错误传递到不是 validator.ValidationErrors 的函数中。

    所以要么确保其他错误不会传递到NewValidatorError。或者做一个更安全的类型检查,比如:

    errs, ok := err.(validator.ValidationErrors)
    if !ok {
      // handles other err type
    }
    

    更多信息:A Tour of Go - type assertionsA Tour of Go - type switches

    【讨论】:

      【解决方案2】:

      我添加了对 UnmarshalTypeError 的检查,如下所示:

          if reflect.TypeOf(err).Elem().String() == "json.UnmarshalTypeError" {
              errs := err.(*json.UnmarshalTypeError)
              res.Errors[errs.Field] = fmt.Sprintf("{key: %v}", errs.Error())
      
              return res
          }
      
          errs := err.(validator.ValidationErrors)
      
      

      我猜当 json 是类型提示时,Golang 是严格的。它必须是确切的类型,否则会抛出 UnmarshalTypeError 错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-17
        • 1970-01-01
        • 2015-04-09
        • 1970-01-01
        • 2014-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多