Skip to content

Commit

Permalink
BaseStackTrace util (#4)
Browse files Browse the repository at this point in the history
* `BaseStackTrace` util

* refactor test
  • Loading branch information
taxio authored Jan 8, 2024
1 parent b7a694c commit 43cf304
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 20 deletions.
25 changes: 5 additions & 20 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ func TestNew(t *testing.T) {
if err.Error() != msg {
t.Errorf("expected %s, got %s", msg, err.Error())
}
var cErr *errors.Error
if ok := errors.As(err, &cErr); !ok {
t.Fatal("expected error to be *errors.Error")
}
cErr := mustCast(t, err)
if len(cErr.StackTrace()) == 0 {
t.Errorf("expected stack trace, got empty")
}
Expand Down Expand Up @@ -107,10 +104,7 @@ func TestWrap(t *testing.T) {
if err.Error() != "test" {
t.Errorf("expected test, got %s", err.Error())
}
var cErr *errors.Error
if ok := errors.As(err, &cErr); !ok {
t.Fatal("expected error to be *errors.Error")
}
cErr := mustCast(t, err)
if len(cErr.StackTrace()) == 0 {
t.Errorf("expected stack trace, got empty")
}
Expand All @@ -120,10 +114,7 @@ func TestWrap(t *testing.T) {
func TestWithAttrs(t *testing.T) {
t.Run("empty", func(t *testing.T) {
err := errors.New("test")
var cErr *errors.Error
if ok := errors.As(err, &cErr); !ok {
t.Fatal("expected error to be *errors.Error")
}
cErr := mustCast(t, err)
if len(cErr.Attributes()) != 0 {
t.Errorf("expected 0 attributes, got %d", len(cErr.Attributes()))
}
Expand All @@ -137,10 +128,7 @@ func TestWithAttrs(t *testing.T) {
),
)
err := errors.Wrap(baseErr)
var cErr *errors.Error
if ok := errors.As(err, &cErr); !ok {
t.Fatal("expected error to be *errors.Error")
}
cErr := mustCast(t, err)
if len(cErr.Attributes()) != 1 {
t.Errorf("expected 1 attribute, got %d", len(cErr.Attributes()))
}
Expand All @@ -164,10 +152,7 @@ func TestWithAttrs(t *testing.T) {
errors.Attr("key3", "value3"),
),
)
var cErr *errors.Error
if ok := errors.As(err, &cErr); !ok {
t.Fatal("expected error to be *errors.Error")
}
cErr := mustCast(t, err)
if len(cErr.Attributes()) != 3 {
t.Errorf("expected 1 attribute, got %d", len(cErr.Attributes()))
}
Expand Down
21 changes: 21 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package errors

func BaseStackTrace(err error) []uintptr {
if err == nil {
return nil
}
return baseStackTrace(err)
}

func baseStackTrace(err error) []uintptr {
x, ok := err.(interface{ StackTrace() []uintptr })
if !ok {
return nil
}
stackTrace := x.StackTrace()
childStackTrace := baseStackTrace(Unwrap(err))
if len(childStackTrace) == 0 {
return stackTrace
}
return childStackTrace
}
82 changes: 82 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package errors_test

import (
stderr "errors"
"testing"

"github.com/taxio/errors"
)

func TestBaseStackTrace(t *testing.T) {
t.Run("nil", func(t *testing.T) {
got := errors.BaseStackTrace(nil)
if len(got) != 0 {
t.Errorf("expected empty, got %v", got)
}
})

t.Run("other error", func(t *testing.T) {
got := errors.BaseStackTrace(stderr.New("test"))
if len(got) != 0 {
t.Errorf("expected empty, got %v", got)
}
})

t.Run("single error", func(t *testing.T) {
err := errors.New("test")
cErr := mustCast(t, err)

got := errors.BaseStackTrace(err)
if len(cErr.StackTrace()) != len(got) {
t.Fatalf("expected %d, got %d", len(cErr.StackTrace()), len(got))
}
for i, st := range cErr.StackTrace() {
if got[i] != st {
t.Errorf("expected %v, got %v", st, got[i])
}
}
})

t.Run("nested", func(t *testing.T) {
baseErr := errors.New("base")
cBaseErr := mustCast(t, baseErr)
wrapErr1 := errors.Wrap(baseErr)
wrapErr2 := errors.Wrap(wrapErr1)

got := errors.BaseStackTrace(wrapErr2)
if len(cBaseErr.StackTrace()) != len(got) {
t.Fatalf("expected %d, got %d", len(cBaseErr.StackTrace()), len(got))
}
for i, st := range cBaseErr.StackTrace() {
if got[i] != st {
t.Errorf("expected %v, got %v", st, got[i])
}
}
})

t.Run("nested with other base error", func(t *testing.T) {
baseErr := stderr.New("base")
wrapErr1 := errors.Wrap(baseErr)
cWrapErr1 := mustCast(t, wrapErr1)
wrapErr2 := errors.Wrap(wrapErr1)

got := errors.BaseStackTrace(wrapErr2)
if len(cWrapErr1.StackTrace()) != len(got) {
t.Fatalf("expected %d, got %d", len(cWrapErr1.StackTrace()), len(got))
}
for i, st := range cWrapErr1.StackTrace() {
if got[i] != st {
t.Errorf("expected %v, got %v", st, got[i])
}
}
})
}

func mustCast(t *testing.T, err error) *errors.Error {
t.Helper()
var cErr *errors.Error
if !errors.As(err, &cErr) {
t.Fatalf("expected error to be *errors.Error")
}
return cErr
}

0 comments on commit 43cf304

Please sign in to comment.