Skip to content

Commit

Permalink
bug fix error kind
Browse files Browse the repository at this point in the history
  • Loading branch information
tarunKoyalwar committed May 22, 2024
1 parent 5361171 commit 389764f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
28 changes: 28 additions & 0 deletions errkit/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/pkg/errors"
errorutil "github.com/projectdiscovery/utils/errors"
"github.com/stretchr/testify/require"
"go.uber.org/multierr"

stderrors "errors"
Expand Down Expand Up @@ -77,3 +78,30 @@ func TestErrorUtil(t *testing.T) {
t.Fatal("expected 3 errors")
}
}

func TestErrKindCheck(t *testing.T) {
x := New("port closed or filtered").SetKind(ErrKindNetworkPermanent)
t.Run("Errkind With Normal Error", func(t *testing.T) {
wrapped := Wrap(x, "this is a wrapped error")
if !IsKind(wrapped, ErrKindNetworkPermanent) {
t.Fatal("expected to be able to find the original error")
}
})

// mix of multiple kinds
tmp := New("i/o timeout").SetKind(ErrKindNetworkTemporary)
t.Run("Errkind With Multiple Kinds", func(t *testing.T) {
wrapped := Append(x, tmp)
errx := FromError(wrapped)
val, ok := errx.kind.(*multiKind)
require.True(t, ok, "expected to be able to find the original error")
require.Equal(t, 2, len(val.kinds))
})

// duplicate kinds
t.Run("Errkind With Duplicate Kinds", func(t *testing.T) {
wrapped := Append(x, x)
errx := FromError(wrapped)
require.True(t, errx.kind.Is(ErrKindNetworkPermanent), "expected to be able to find the original error")
})
}
38 changes: 36 additions & 2 deletions errkit/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ var (
ErrKindUnknown = NewPrimitiveErrKind("unknown-error", "unknown error", nil)
)

var (
// DefaultErrorKinds is the default error kinds used in classification
// if one intends to add more default error kinds it must be done in init() function
// of that package to avoid race conditions
DefaultErrorKinds = []ErrKind{
ErrKindNetworkTemporary,
ErrKindNetworkPermanent,
ErrKindDeadline,
}
)

// ErrKind is an interface that represents a kind of error
type ErrKind interface {
// Is checks if current error kind is same as given error kind
Expand Down Expand Up @@ -110,6 +121,11 @@ func isNetworkPermanentErr(err *ErrorX) bool {
return true
case strings.Contains(v, "could not resolve host"):
return true
case strings.Contains(v, "port closed or filtered"):
// pd standard error for port closed or filtered
return true
case strings.Contains(v, "connect: connection refused"):
return true
}
return false
}
Expand Down Expand Up @@ -192,7 +208,7 @@ func CombineErrKinds(kind ...ErrKind) ErrKind {
f := &multiKind{}
uniq := map[ErrKind]struct{}{}
for _, k := range kind {
if k == nil {
if k == nil || k.String() == "" {
continue
}
if val, ok := k.(*multiKind); ok {
Expand All @@ -206,15 +222,27 @@ func CombineErrKinds(kind ...ErrKind) ErrKind {
all := maps.Keys(uniq)
for _, k := range all {
for u := range uniq {
if k.IsParent(u) || k.Is(u) {
if k.IsParent(u) {
delete(uniq, u)
}
}
}
if len(uniq) > 1 {
// check and remove unknown error kind
for k := range uniq {
if k.Is(ErrKindUnknown) {
delete(uniq, k)
}
}
}

f.kinds = maps.Keys(uniq)
if len(f.kinds) > MaxErrorDepth {
f.kinds = f.kinds[:MaxErrorDepth]
}
if len(f.kinds) == 1 {
return f.kinds[0]
}
return f
}

Expand All @@ -237,6 +265,12 @@ func GetErrorKind(err error, defs ...ErrKind) ErrKind {
return def
}
}
// check in default error kinds
for _, def := range DefaultErrorKinds {
if def.Represents(x) {
return def
}
}
return ErrKindUnknown
}

Expand Down

0 comments on commit 389764f

Please sign in to comment.