diff --git a/errors.go b/errors.go index 161aea25..84bade4b 100644 --- a/errors.go +++ b/errors.go @@ -106,6 +106,29 @@ func New(message string) error { } } +// ExistStack return an error already with stack +// ExistStack will check all parent error +func ExistStack(err error) bool { + type stackTracer interface { + StackTrace() StackTrace + } + if _, ok := err.(stackTracer); ok { + return true + } + type causer interface { + Cause() error + } + if value, ok := err.(causer); ok { + return ExistStack(value.Cause()) + } else { + return false + } + cause, ok := err.(causer) + if !ok { + return false + } + return ExistStack(cause.Cause()) +} // Errorf formats according to a format specifier and returns the string // as a value that satisfies error. // Errorf also records the stack trace at the point it was called. diff --git a/errors_test.go b/errors_test.go index 2089b2f7..6b0b6db9 100644 --- a/errors_test.go +++ b/errors_test.go @@ -27,6 +27,23 @@ func TestNew(t *testing.T) { } } +func TestExistStack(t *testing.T) { + tests := []struct { + err error + want bool + }{ + {io.EOF, false}, + {Wrap(io.EOF, "read error"), true}, + } + + for _, tt := range tests { + got := ExistStack(tt.err) + if got != tt.want { + t.Errorf("ExistStack(%v): got: %v, want %v", tt.err, got, tt.want) + } + } +} + func TestWrapNil(t *testing.T) { got := Wrap(nil, "no error") if got != nil {