-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UnmarshalTypeError hook support ??? #5
Comments
other chose, can provide a error handle interface, while Unmarshal error, call interface method, get result |
//////////// append ///////////
// UnmarshalErrHandler while decode error, will inject this handler, catch error.
// if you want to ignore this error, you can return nil
type UnmarshalErrHandler func(err error) error
var (
usedUnmarshalErrHandlerHook atomic.Bool
unmarshalErrHandlerHook UnmarshalErrHandler = func(err error) error { return err }
)
// UseUnmarshalErrHandler register a yourself error handler, only once
func UseUnmarshalErrHandler(handler UnmarshalErrHandler) {
if usedUnmarshalErrHandlerHook.Swap(true) {
return
}
unmarshalErrHandlerHook = handler
}
//////////// rewrite ///////////
// error aborts the decoding by panicking with err.
func (d *decodeState) error(err error) {
if e := unmarshalErrHandlerHook(err); e != nil {
panic(err)
} else {
d.savedError = e
}
}
// saveError saves the first err it is called with,
// for reporting at the end of the unmarshal.
func (d *decodeState) saveError(err error) {
if e := unmarshalErrHandlerHook(err); e == nil {
d.savedError = e
} else {
if d.savedError == nil {
d.savedError = err
}
}
} for example here: func TestErrHandler(t *testing.T) {
type ErrHandlerStruct struct {
VarName string `json:"varname,omitempty"`
Required string `json:"required,omitempty"`
Mode string `json:"mode,omitempty"`
Title string `json:"title,omitempty"`
Value string `json:"value,omitempty"`
ImageUrl string `json:"imageUrl,omitempty"`
Size int `json:"size,omitempty"`
}
data := `[
{
title: '我的头像',
value: '"{{ .AvatarUrl}}"',
imageUrl: 'https://www.AvatarUrlImage.com',
VarName: 666,
},
{
title: '我的昵称',
value: "{{.NickName}}",
size: '{{.Size}}',
imageUrl: 'https://www.NickNameImage.com'
}
]`
UseUnmarshalErrHandler(func(err error) error {
if err != nil {
switch {
case strings.Contains(err.Error(), "json: invalid use of ,string"):
return nil
case strings.Contains(err.Error(), "json: cannot unmarshal string"):
return nil
case strings.Contains(err.Error(), "json: cannot unmarshal number into Go value of type string"):
return nil
}
}
return err
})
var res []*ErrHandlerStruct
dec := NewDecoder(strings.NewReader(data))
err := dec.Decode(&res)
if err == nil {
fmt.Printf("NewDecoder result: %+v\n", res)
} else {
fmt.Printf("NewDecoder result: %+v err: %v\n", res, err)
}
if len(res) != 2 {
t.Errorf("Decode: result len is not match")
}
if err != nil {
t.Errorf("Decode: error not nil")
}
var res2 []*ErrHandlerStruct
err2 := Unmarshal([]byte(data), &res2)
if err2 == nil {
fmt.Printf("Unmarshal result: %+v\n", res2)
} else {
fmt.Printf("Unmarshal result: %+v err: %v\n", res2, err2)
}
if len(res2) != 2 {
t.Errorf("Unmarshal: result len is not match")
}
if err2 != nil {
t.Errorf("Unmarshal: error not nil")
}
} |
add pr: #6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
result:
{"code":"0","float_num":"0","Code2":"999","Data":"字符串数据","-":2000}
json: cannot unmarshal number 666w into Go value of type int
can we get ,parse int failed, use default value ?
number:
int, int32, int64, uint32, uint64 ... -> 0
float32 float64 -> 0.0
maybe , you can provide a hook, while ParseInt , ParseFloat
The text was updated successfully, but these errors were encountered: