mirror of
https://gitee.com/johng/gf.git
synced 2024-11-29 18:57:44 +08:00
improve error handling for custom validation rule for package gvalid
This commit is contained in:
parent
1a7450b9e9
commit
ce16dad88f
@ -97,7 +97,7 @@ func (set *Set) AddIfNotExist(item interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddIfNotExistFunc checks whether item exists in the set,
|
// AddIfNotExistFunc checks whether item exists in the set,
|
||||||
// it adds the item to set and returns true if it does not exists in the set and
|
// it adds the item to set and returns true if it does not exist in the set and
|
||||||
// function `f` returns true, or else it does nothing and returns false.
|
// function `f` returns true, or else it does nothing and returns false.
|
||||||
//
|
//
|
||||||
// Note that, if `item` is nil, it does nothing and returns false. The function `f`
|
// Note that, if `item` is nil, it does nothing and returns false. The function `f`
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
type Error struct {
|
type Error struct {
|
||||||
error error // Wrapped error.
|
error error // Wrapped error.
|
||||||
stack stack // Stack array, which records the stack information when this error is created or wrapped.
|
stack stack // Stack array, which records the stack information when this error is created or wrapped.
|
||||||
text string // Error text, which is created by New* functions.
|
text string // Custom Error text when Error is created, might be empty when its code is not nil.
|
||||||
code gcode.Code // Error code if necessary.
|
code gcode.Code // Error code if necessary.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +31,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// goRootForFilter is used for stack filtering purpose.
|
// goRootForFilter is used for stack filtering in development environment purpose.
|
||||||
// Mainly for development environment.
|
|
||||||
goRootForFilter = runtime.GOROOT()
|
goRootForFilter = runtime.GOROOT()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -107,18 +106,18 @@ func (err *Error) Format(s fmt.State, verb rune) {
|
|||||||
switch {
|
switch {
|
||||||
case s.Flag('-'):
|
case s.Flag('-'):
|
||||||
if err.text != "" {
|
if err.text != "" {
|
||||||
io.WriteString(s, err.text)
|
_, _ = io.WriteString(s, err.text)
|
||||||
} else {
|
} else {
|
||||||
io.WriteString(s, err.Error())
|
_, _ = io.WriteString(s, err.Error())
|
||||||
}
|
}
|
||||||
case s.Flag('+'):
|
case s.Flag('+'):
|
||||||
if verb == 's' {
|
if verb == 's' {
|
||||||
io.WriteString(s, err.Stack())
|
_, _ = io.WriteString(s, err.Stack())
|
||||||
} else {
|
} else {
|
||||||
io.WriteString(s, err.Error()+"\n"+err.Stack())
|
_, _ = io.WriteString(s, err.Error()+"\n"+err.Stack())
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
io.WriteString(s, err.Error())
|
_, _ = io.WriteString(s, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,6 +175,14 @@ func (err *Error) Next() error {
|
|||||||
return err.error
|
return err.error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCode updates the internal code with given code.
|
||||||
|
func (err *Error) SetCode(code gcode.Code) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err.code = code
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||||
// Note that do not use pointer as its receiver here.
|
// Note that do not use pointer as its receiver here.
|
||||||
func (err *Error) MarshalJSON() ([]byte, error) {
|
func (err *Error) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -311,6 +311,18 @@ func Test_Code(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_SetCode(t *testing.T) {
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
err := gerror.New("123")
|
||||||
|
t.Assert(gerror.Code(err), -1)
|
||||||
|
t.Assert(err.Error(), "123")
|
||||||
|
|
||||||
|
err.(*gerror.Error).SetCode(gcode.CodeValidationFailed)
|
||||||
|
t.Assert(gerror.Code(err), gcode.CodeValidationFailed)
|
||||||
|
t.Assert(err.Error(), "123")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Json(t *testing.T) {
|
func Test_Json(t *testing.T) {
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
err := gerror.Wrap(gerror.New("1"), "2")
|
err := gerror.Wrap(gerror.New("1"), "2")
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/gogf/gf/v2/container/gvar"
|
"github.com/gogf/gf/v2/container/gvar"
|
||||||
"github.com/gogf/gf/v2/errors/gcode"
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
"github.com/gogf/gf/v2/text/gstr"
|
"github.com/gogf/gf/v2/text/gstr"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -134,13 +135,23 @@ func (v *Validator) doCheckValue(ctx context.Context, input doCheckValueInput) E
|
|||||||
if customRuleFunc != nil {
|
if customRuleFunc != nil {
|
||||||
// It checks custom validation rules with most priority.
|
// It checks custom validation rules with most priority.
|
||||||
message := v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
message := v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||||
if err := customRuleFunc(ctx, RuleFuncInput{
|
if err = customRuleFunc(ctx, RuleFuncInput{
|
||||||
Rule: ruleItems[index],
|
Rule: ruleItems[index],
|
||||||
Message: message,
|
Message: message,
|
||||||
Value: gvar.New(input.Value),
|
Value: gvar.New(input.Value),
|
||||||
Data: gvar.New(input.DataRaw),
|
Data: gvar.New(input.DataRaw),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
match = false
|
match = false
|
||||||
|
// The error should have stack info to indicate the error position.
|
||||||
|
if !gerror.HasStack(err) {
|
||||||
|
err = gerror.NewCodeSkip(gcode.CodeValidationFailed, 1, err.Error())
|
||||||
|
}
|
||||||
|
// The error should have error code that is `gcode.CodeValidationFailed`.
|
||||||
|
if gerror.Code(err) == gcode.CodeNil {
|
||||||
|
if e, ok := err.(*gerror.Error); ok {
|
||||||
|
e.SetCode(gcode.CodeValidationFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
ruleErrorMap[ruleKey] = err
|
ruleErrorMap[ruleKey] = err
|
||||||
} else {
|
} else {
|
||||||
match = true
|
match = true
|
||||||
|
@ -10,7 +10,7 @@ import "context"
|
|||||||
|
|
||||||
// getErrorMessageByRule retrieves and returns the error message for specified rule.
|
// getErrorMessageByRule retrieves and returns the error message for specified rule.
|
||||||
// It firstly retrieves the message from custom message map, and then checks i18n manager,
|
// It firstly retrieves the message from custom message map, and then checks i18n manager,
|
||||||
// it returns the default error message if it's not found in custom message map or i18n manager.
|
// it returns the default error message if it's not found in neither custom message map nor i18n manager.
|
||||||
func (v *Validator) getErrorMessageByRule(ctx context.Context, ruleKey string, customMsgMap map[string]string) string {
|
func (v *Validator) getErrorMessageByRule(ctx context.Context, ruleKey string, customMsgMap map[string]string) string {
|
||||||
content := customMsgMap[ruleKey]
|
content := customMsgMap[ruleKey]
|
||||||
if content != "" {
|
if content != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user