From 1af1684d241ac22a4f6abd4960456e944cd950a2 Mon Sep 17 00:00:00 2001 From: fgy Date: Fri, 22 Sep 2023 15:48:01 +0800 Subject: [PATCH] fix: set validator error --- pkg/app/server/binding/binder_test.go | 54 +++++++++++++++++++++++++++ pkg/app/server/binding/config.go | 6 +-- pkg/app/server/binding/default.go | 4 +- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/pkg/app/server/binding/binder_test.go b/pkg/app/server/binding/binder_test.go index d106ed7ad..f1340448f 100644 --- a/pkg/app/server/binding/binder_test.go +++ b/pkg/app/server/binding/binder_test.go @@ -1436,6 +1436,60 @@ func Test_BindHeaderNormalize(t *testing.T) { assert.DeepEqual(t, "", result3.Header) } +type ValidateError struct { + ErrType, FailField, Msg string +} + +// Error implements error interface. +func (e *ValidateError) Error() string { + if e.Msg != "" { + return e.ErrType + ": expr_path=" + e.FailField + ", cause=" + e.Msg + } + return e.ErrType + ": expr_path=" + e.FailField + ", cause=invalid" +} + +func Test_ValidatorErrorFactory(t *testing.T) { + type TestBind struct { + A string `query:"a,required"` + } + + r := protocol.NewRequest("GET", "/foo", nil) + r.SetRequestURI("/foo/bar?b=20") + CustomValidateErrFunc := func(failField, msg string) error { + err := ValidateError{ + ErrType: "validateErr", + FailField: "[validateFailField]: " + failField, + Msg: "[validateErrMsg]: " + msg, + } + + return &err + } + + validateConfig := NewValidateConfig() + validateConfig.SetValidatorErrorFactory(CustomValidateErrFunc) + + var req TestBind + err := Bind(r, &req, nil) + if err == nil { + t.Fatalf("unexpected nil, expected an error") + } + + type TestValidate struct { + B int `query:"b" vd:"$>100"` + } + + var reqValidate TestValidate + err = Bind(r, &reqValidate, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + err = Validate(&reqValidate) + if err == nil { + t.Fatalf("unexpected nil, expected an error") + } + assert.DeepEqual(t, "validateErr: expr_path=[validateFailField]: B, cause=[validateErrMsg]: ", err.Error()) +} + func Benchmark_Binding(b *testing.B) { type Req struct { Version string `path:"v"` diff --git a/pkg/app/server/binding/config.go b/pkg/app/server/binding/config.go index c122c54c6..53fa7aa7f 100644 --- a/pkg/app/server/binding/config.go +++ b/pkg/app/server/binding/config.go @@ -162,9 +162,5 @@ func (config *ValidateConfig) MustRegValidateFunc(funcName string, fn func(args // SetValidatorErrorFactory customizes the factory of validation error. func (config *ValidateConfig) SetValidatorErrorFactory(validatingErrFactory func(failField, msg string) error) { - if val, ok := DefaultValidator().(*defaultValidator); ok { - val.validate.SetErrorFactory(validatingErrFactory) - } else { - panic("customized validator can not use 'SetValidatorErrorFactory'") - } + validator.SetErrorFactory(validatingErrFactory) } diff --git a/pkg/app/server/binding/default.go b/pkg/app/server/binding/default.go index 28bbc5311..d790e1539 100644 --- a/pkg/app/server/binding/default.go +++ b/pkg/app/server/binding/default.go @@ -379,7 +379,9 @@ type defaultValidator struct { } func NewDefaultValidator(config *ValidateConfig) StructValidator { - return &defaultValidator{} + vd := &defaultValidator{} + vd.lazyinit() + return vd } // ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.