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,
|
||||
// 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.
|
||||
//
|
||||
// Note that, if `item` is nil, it does nothing and returns false. The function `f`
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
type Error struct {
|
||||
error error // Wrapped error.
|
||||
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.
|
||||
}
|
||||
|
||||
@ -31,8 +31,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// goRootForFilter is used for stack filtering purpose.
|
||||
// Mainly for development environment.
|
||||
// goRootForFilter is used for stack filtering in development environment purpose.
|
||||
goRootForFilter = runtime.GOROOT()
|
||||
)
|
||||
|
||||
@ -107,18 +106,18 @@ func (err *Error) Format(s fmt.State, verb rune) {
|
||||
switch {
|
||||
case s.Flag('-'):
|
||||
if err.text != "" {
|
||||
io.WriteString(s, err.text)
|
||||
_, _ = io.WriteString(s, err.text)
|
||||
} else {
|
||||
io.WriteString(s, err.Error())
|
||||
_, _ = io.WriteString(s, err.Error())
|
||||
}
|
||||
case s.Flag('+'):
|
||||
if verb == 's' {
|
||||
io.WriteString(s, err.Stack())
|
||||
_, _ = io.WriteString(s, err.Stack())
|
||||
} else {
|
||||
io.WriteString(s, err.Error()+"\n"+err.Stack())
|
||||
_, _ = io.WriteString(s, err.Error()+"\n"+err.Stack())
|
||||
}
|
||||
default:
|
||||
io.WriteString(s, err.Error())
|
||||
_, _ = io.WriteString(s, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,6 +175,14 @@ func (err *Error) Next() 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.
|
||||
// Note that do not use pointer as its receiver here.
|
||||
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) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err := gerror.Wrap(gerror.New("1"), "2")
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"errors"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -134,13 +135,23 @@ func (v *Validator) doCheckValue(ctx context.Context, input doCheckValueInput) E
|
||||
if customRuleFunc != nil {
|
||||
// It checks custom validation rules with most priority.
|
||||
message := v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
if err := customRuleFunc(ctx, RuleFuncInput{
|
||||
if err = customRuleFunc(ctx, RuleFuncInput{
|
||||
Rule: ruleItems[index],
|
||||
Message: message,
|
||||
Value: gvar.New(input.Value),
|
||||
Data: gvar.New(input.DataRaw),
|
||||
}); err != nil {
|
||||
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
|
||||
} else {
|
||||
match = true
|
||||
|
@ -10,7 +10,7 @@ import "context"
|
||||
|
||||
// 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 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 {
|
||||
content := customMsgMap[ruleKey]
|
||||
if content != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user