Last active
May 9, 2020 09:58
-
-
Save hungdh0x5e/cd3c6153029a852cbf482b1c62623735 to your computer and use it in GitHub Desktop.
Custom gin validator error message
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Before init Gin | |
err := validation.InitValidator() | |
// In controller or struct validate | |
err := ctx.ShouldBindJSON(&request) | |
if err != nil { | |
for _, fieldErr := range err.(validator.ValidationErrors) { | |
errMsg := errors.New(fieldErr.Translate(validation.CustomTranslator)) | |
vlog.Error(vgin.GetAppContext(ctx), "Failed to bind request body", errMsg) | |
vgin.BuildErrorResponse(ctx, verrors.NewInvalidRequestFormatError(errMsg)) | |
return // exit on first error | |
} | |
} | |
// ===================== | |
package validation | |
import ( | |
"github.com/gin-gonic/gin/binding" | |
"github.com/go-playground/locales/en" | |
ut "github.com/go-playground/universal-translator" | |
"github.com/go-playground/validator/v10" | |
en_translations "github.com/go-playground/validator/v10/translations/en" | |
"gitlab.id.vin/loyalty/loyalty-checkout/common" | |
"log" | |
"reflect" | |
"regexp" | |
"strings" | |
) | |
var CustomTranslator ut.Translator | |
const ( | |
IDByType = "id_by_type" | |
) | |
func InitValidator() error { | |
validate := binding.Validator.Engine().(*validator.Validate) | |
registerTagNameJSON(validate) | |
registerTranslator(validate) | |
_ = registerIDByTypeValidation(validate) | |
return nil | |
} | |
func registerTagNameJSON(validate *validator.Validate) { | |
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { | |
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] | |
if name == "-" { | |
return "" | |
} | |
return name | |
}) | |
} | |
func registerTranslator(validate *validator.Validate) { | |
translator := en.New() | |
uni := ut.New(translator, translator) | |
found := false | |
CustomTranslator, found = uni.GetTranslator("en") | |
if !found { | |
log.Fatal("translator not found") | |
} | |
if err := en_translations.RegisterDefaultTranslations(validate, CustomTranslator); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func registerIDByTypeValidation(validate *validator.Validate) error { | |
err := validate.RegisterValidation(IDByType, validateIDByType) | |
if err != nil { | |
return err | |
} | |
_ = validate.RegisterTranslation(IDByType, CustomTranslator, func(ut ut.Translator) error { | |
return ut.Add(IDByType, "{0} is not valid with id_type", true) // see universal-translator for details | |
}, func(ut ut.Translator, fe validator.FieldError) string { | |
t, _ := ut.T(IDByType, fe.Field()) | |
return t | |
}) | |
return nil | |
} | |
func validateIDByType(fl validator.FieldLevel) bool { | |
idTypeValue, idTypeKind, _, ok := fl.GetStructFieldOK2() | |
if !ok || idTypeKind.String() != "string" { | |
return false | |
} | |
if idTypeValue.String() != common.IDTypeMobile { | |
return true | |
} | |
phoneNumberRegex := regexp.MustCompile("^0\\d{9}$") | |
return phoneNumberRegex.MatchString(fl.Field().String()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example
Request
Response