英文:
Gin Gonic Custom Error Message Fails When Invalid Data Sent
问题
Validator结构体
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
。
这个问题与此问题相关:https://stackoverflow.com/questions/64278486/how-to-assert-error-type-json-unmarshaltypeerror-when-caught-by-gin-c-bindjson
然而,答案并不合理。
英文:
Validator struct
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:"-"`
}
Formatting a custom error as below:
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
}
works when data sent is
{
"email": "me@example.com",
"name": "John Doe",
"mobile_country_code": 1,
"mobile": 1234567
}
but sending an invalid type
{
"email": "me@example.com",
"name": "John Doe",
"mobile_country_code": "1",
"mobile": 1234567
}
throws the error interface conversion: error is *json.UnmarshalTypeError, not validator.ValidationErrors
This question is related to this one: https://stackoverflow.com/questions/64278486/how-to-assert-error-type-json-unmarshaltypeerror-when-caught-by-gin-c-bindjson
however the answers do not make sense.
答案1
得分: 2
根据异常提示,以下代码行无法进行类型转换:
errs := err.(validator.ValidationErrors)
函数中传入了一个不是 *validator.ValidationErrors
类型的错误。
因此,要么确保其他类型的错误不会传递给 NewValidatorError
函数,要么进行更安全的类型检查,例如:
errs, ok := err.(validator.ValidationErrors)
if !ok {
// 处理其他错误类型
}
更多信息:A Tour of Go - 类型断言,A Tour of Go - 类型切换
英文:
As the exception suggests, the following line failed type conversion
errs := err.(validator.ValidationErrors)
A different type of error must have got passed into the function that is not validator.ValidationErrors
.
So either make sure other errors won't be passed into NewValidatorError
. Or do a safer type check like:
errs, ok := err.(validator.ValidationErrors)
if !ok {
// handles other err type
}
More info: A Tour of Go - type assertions, A Tour of Go - type switches
答案2
得分: -1
我为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)
我猜Golang在对JSON进行类型提示时是严格的。它必须是精确的类型,否则会抛出UnmarshalTypeError
错误。
英文:
I added a check for the UnmarshalTypeError as below:
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)
I guess Golang is strict when json is type-hinted. It has to be the exact type otherwise it will throw an UnmarshalTypeError
error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论