Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
better catch multilevel errors
Browse files Browse the repository at this point in the history
  • Loading branch information
im-kulikov committed Apr 30, 2019
1 parent 9fe06c4 commit 113abc6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
15 changes: 9 additions & 6 deletions helium.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,25 @@ func CatchTrace(err error) {
// digging into the root of the problem
for {
var (
ok bool
v = reflect.ValueOf(err)
fn reflect.Value
)

if v.Type().Kind() != reflect.Struct {
break
}

if !v.FieldByName("Reason").IsValid() || !v.FieldByName("Func").IsValid() {
} else if !v.FieldByName("Reason").IsValid() {
break
} else if v.FieldByName("Func").IsValid() {
fn = v.FieldByName("Func")
}

fn = v.FieldByName("Func")
err = v.FieldByName("Reason").Interface().(error)

fmt.Printf("Place: %#v\nReason: %s\n\n", fn, err)

if err, ok = v.FieldByName("Reason").Interface().(error); !ok {
err = v.Interface().(error)
break
}
}

panic(err)
Expand Down
32 changes: 32 additions & 0 deletions helium_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/ioutil"
"log"
"os"
"strconv"
"testing"

"bou.ke/monkey"
Expand All @@ -25,6 +26,12 @@ type (
heliumErrApp struct{}

Error string

TestError struct {
Index int
Func interface{}
Reason error
}
)

const ErrTest = Error("test")
Expand All @@ -33,6 +40,10 @@ func (e Error) Error() string {
return string(e)
}

func (e TestError) Error() string {
return "error level: " + strconv.Itoa(e.Index)
}

func (h heliumApp) Run(ctx context.Context) error { return nil }
func (h heliumErrApp) Run(ctx context.Context) error { return ErrTest }

Expand Down Expand Up @@ -253,5 +264,26 @@ func TestHelium(t *testing.T) {

require.Empty(t, exitCode)
})

t.Run("should catch multi level errors", func(t *testing.T) {
var exitCode int

monkey.Patch(os.Exit, func(code int) { exitCode = code; panic(code) })
monkey.Patch(log.Fatal, func(...interface{}) { exitCode = 2; panic(exitCode) })

require.Panics(t, func() {
CatchTrace(TestError{
Index: 1,
Reason: TestError{
Index: 2,
Reason: TestError{
Index: 3,
},
},
})
})

require.Empty(t, exitCode)
})
})
}

0 comments on commit 113abc6

Please sign in to comment.