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": "[email protected]",
"name": "John Doe",
"mobile_country_code": 1,
"mobile": 1234567
}
but sending an invalid type
{
"email": "[email protected]",
"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: How to assert error type json.UnmarshalTypeError when caught by gin c.BindJSON however the answers do not make sense.
CodePudding user response:
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
CodePudding user response:
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.