Skip to content

Commit

Permalink
fixed: safety get target Error() in Is() to avoid panic
Browse files Browse the repository at this point in the history
- old Is raised panic when using `errors.Is(err, &strconv.NumError{})`, even though this is not a good usage

Signed-off-by: Hedzr Yeh <[email protected]>
  • Loading branch information
hedzr committed Oct 15, 2023
1 parent 1a5e18f commit bfd635e
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions asisunwrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func Is(err, target error) bool {
// target is not Code-based, try convert source err with target's type, and test whether its plain text message is equal
var savedMsg string
if !isNil(tv) {
savedMsg = target.Error()
savedMsg = safeErrorGetMsg(target)
}
for {
if isComparable {
Expand All @@ -119,7 +119,7 @@ func Is(err, target error) bool {
return true
}
if _, ok := target.(Code); !ok {
if ok = As(err, &target); ok && !isNil(reflect.ValueOf(target)) && strings.EqualFold(target.Error(), savedMsg) {
if ok = As(err, &target); ok && !isNil(reflect.ValueOf(target)) && strings.EqualFold(safeErrorGetMsg(target), savedMsg) {
return true
}
}
Expand All @@ -132,6 +132,18 @@ func Is(err, target error) bool {
}
}

func safeErrorGetMsg(err error) (msg string) {
if err != nil {
defer func() {
if e := recover(); e != nil {
fmt.Printf("some error recovered: %v", e)
}
}()
msg = err.Error()
}
return
}

// isNil for go1.12+, the difference is it never panic on unavailable kinds.
// see also reflect.IsNil.
func isNil(v reflect.Value) bool {
Expand Down

0 comments on commit bfd635e

Please sign in to comment.