From 9ca9d6c4bdf205445aca8625aebfd145902dd0a2 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 9 Jul 2019 10:40:26 +0800 Subject: [PATCH] add Cause function for gerror --- g/errors/gerror/gerror.go | 10 ++++++++++ g/errors/gerror/gerror_error.go | 17 +++++++++++++++++ g/errors/gerror/gerror_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/g/errors/gerror/gerror.go b/g/errors/gerror/gerror.go index 29605bb1e..99f52fad2 100644 --- a/g/errors/gerror/gerror.go +++ b/g/errors/gerror/gerror.go @@ -58,6 +58,16 @@ func Wrapf(err error, format string, args ...interface{}) error { } } +// Cause returns the root cause error. +func Cause(err error) error { + if err != nil { + if e, ok := err.(*Error); ok { + return e.Cause() + } + } + return err +} + // Stack returns the stack callers as string. // It returns an empty string id the does not support stacks. func Stack(err error) string { diff --git a/g/errors/gerror/gerror_error.go b/g/errors/gerror/gerror_error.go index c92158159..95f6c1bb7 100644 --- a/g/errors/gerror/gerror_error.go +++ b/g/errors/gerror/gerror_error.go @@ -47,6 +47,23 @@ func (err *Error) Error() string { return err.error.Error() } +// Cause returns the root cause error. +func (err *Error) Cause() error { + loop := err + for loop != nil { + if loop.error != nil { + if e, ok := loop.error.(*Error); ok { + loop = e + } else { + return loop.error + } + } else { + return loop + } + } + return nil +} + // Format formats the frame according to the fmt.Formatter interface. // // %v, %s : Print the error string; diff --git a/g/errors/gerror/gerror_test.go b/g/errors/gerror/gerror_test.go index b14053ea9..e1a040f33 100644 --- a/g/errors/gerror/gerror_test.go +++ b/g/errors/gerror/gerror_test.go @@ -48,6 +48,32 @@ func Test_Wrap(t *testing.T) { }) } +func Test_Cause(t *testing.T) { + gtest.Case(t, func() { + err := errors.New("1") + gtest.Assert(gerror.Cause(err), err) + }) + + gtest.Case(t, func() { + err := errors.New("1") + err = gerror.Wrap(err, "2") + err = gerror.Wrap(err, "3") + gtest.Assert(gerror.Cause(err), "1") + }) + + gtest.Case(t, func() { + err := gerror.New("1") + gtest.Assert(gerror.Cause(err), "1") + }) + + gtest.Case(t, func() { + err := gerror.New("1") + err = gerror.Wrap(err, "2") + err = gerror.Wrap(err, "3") + gtest.Assert(gerror.Cause(err), "1") + }) +} + func Test_Format(t *testing.T) { gtest.Case(t, func() { err := errors.New("1")