From 170da521a2338e92663f60c9f33ef4d56452e0bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=91=E8=BE=89?= Date: Mon, 13 Jul 2020 18:14:40 +0800 Subject: [PATCH] fix: update --- Makefile | 2 +- README.md | 4 ++-- util.go | 25 +++++++------------- xerror.go | 21 +++++++++++++---- xerror_core/core.go | 7 ++++++ xerror_test.go | 56 +++++++++++++++------------------------------ 6 files changed, 54 insertions(+), 61 deletions(-) create mode 100644 xerror_core/core.go diff --git a/Makefile b/Makefile index b3a1918..95e889c 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ rm_test: .PHONY: test_profile test_profile: - @go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out example_test.go + @go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out xerror_test.go @go tool pprof -http=":8081" profile.out .PHONY: build diff --git a/README.md b/README.md index d651ddf..46fe58a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ go error 简单实现 ## 性能分析 ```sh -go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out +go test -bench=. -benchmem -memprofile memprofile.out -cpuprofile profile.out ./... go tool pprof -http=":8081" profile.out go tool pprof -http=":8081" memprofile.out ``` @@ -14,7 +14,7 @@ go tool pprof -http=":8081" memprofile.out goos: darwin goarch: amd64 pkg: github.com/pubgo/xerror -BenchmarkPanic-8 403794 2991 ns/op 382 B/op 7 allocs/op +BenchmarkPanic-8 3887112 311 ns/op 64 B/op 1 allocs/op BenchmarkNoPanic-8 188605891 6.46 ns/op 0 B/op 0 allocs/op PASS ok github.com/pubgo/xerror 4.363s diff --git a/util.go b/util.go index 927a49e..857222a 100644 --- a/util.go +++ b/util.go @@ -1,7 +1,9 @@ package xerror import ( + "errors" "fmt" + "github.com/pubgo/xerror/xerror_core" "reflect" "runtime" "strconv" @@ -16,9 +18,9 @@ func handleErr(err *error, _err interface{}) { case error: *err = _err case string: - *err = New("error", _err) + *err = errors.New(_err) default: - *err = New(ErrUnknownType.Code, fmt.Sprintf("%v", _err)) + *err = New(ErrUnknownType.Code, fmt.Sprintf("%+v", _err)) } } @@ -39,6 +41,10 @@ type frame uintptr func (f frame) pc() uintptr { return uintptr(f) - 1 } func callerWithDepth(callDepths ...int) string { + if !xerror_core.IsCaller { + return "" + } + var cd = callDepth if len(callDepths) > 0 { cd = callDepths[0] @@ -92,18 +98,3 @@ func trans(err error) *xerror { } } } - -func isXerror(err error) bool { - if err == nil { - return false - } - - switch err.(type) { - case *xerrorBase: - return true - case *xerror: - return true - default: - return false - } -} diff --git a/xerror.go b/xerror.go index c8100d8..b67499b 100644 --- a/xerror.go +++ b/xerror.go @@ -50,9 +50,15 @@ func RespErr(err *error) { func Resp(f func(err XErr)) { var err error handleErr(&err, recover()) - if err != nil { + if err == nil { + return + } + + if err, ok := err.(XErr); ok { f(err.(XErr)) + return } + f(&xerror{Cause1: err, Caller: callerWithDepth(callDepth + 1)}) } func RespExit() { @@ -188,17 +194,21 @@ func Is(err, target error) bool { } isComparable := reflect.TypeOf(target).Comparable() - for { + for !isErrNil(err) { if isComparable && err == target { return true } if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { return true } - if err = Unwrap(err); isErrNil(err) { + + if wrap, ok := err.(interface{ Unwrap() error }); !ok { return false + } else { + err = wrap.Unwrap() } } + return false } var ( @@ -230,7 +240,10 @@ func As(err error, target interface{}) bool { if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { return true } - err = Unwrap(err) + wrap, ok := err.(interface{ Unwrap() error }) + if ok { + err = wrap.Unwrap() + } } return false } diff --git a/xerror_core/core.go b/xerror_core/core.go new file mode 100644 index 0000000..80b6e80 --- /dev/null +++ b/xerror_core/core.go @@ -0,0 +1,7 @@ +package xerror_core + +var IsCaller bool + +func init() { + IsCaller = true +} diff --git a/xerror_test.go b/xerror_test.go index a3735fd..a34b97e 100644 --- a/xerror_test.go +++ b/xerror_test.go @@ -1,51 +1,31 @@ package xerror_test import ( - "encoding/json" "fmt" "github.com/pubgo/xerror" "github.com/pubgo/xerror/errs" + "github.com/pubgo/xerror/xerror_core" "testing" ) -func init22(a ...interface{}) (err error) { +func a1(a ...interface{}) (err error) { defer xerror.RespErr(&err) - - //fmt.Println(a...) - //xrr.Panic(fmt.Errorf("ss")) - //Exit(New("")) - //_ = fmt.Sprintf("ss") - //_ = fmt.Errorf("ss") - //_ = "ss" + "sss" - //xrr.Panic(nil) - //xerror.PanicF(nil, "sssss %#v", a) - xerror.PanicF(errs.ErrBadRequest, "ssssss wrap") - //xerror.PanicF(fmt.Errorf("ss"), "sssss %#v", a) + xerror.PanicF(errs.ErrBadRequest, "test %+v", a) return } -func init21(a ...interface{}) (err error) { +func a2(a ...interface{}) (err error) { defer xerror.RespErr(&err) - //defer xerror.Resp(func(_err xerror.XErr) { - //fmt.Println(_err.Stack()) - //_ = _err.Error() - //fmt.Println(_err.Error(), _err.Code()) - //}) - - //fmt.Println(a...) - //xrr.Panic(fmt.Errorf("ss")) - //xrr.PanicF(init22(a...), "sssss %#v", a) - xerror.Panic(init22(a...)) + xerror.Panic(a1(a...)) return } func TestName(t *testing.T) { - sss:=init21(1, 2, 3) - dt, _ := json.Marshal(sss) - fmt.Println( string(dt)) - xerror.Exit(sss) - - //Exit(init21(1, 2, 3)) + xerror_core.IsCaller = false + defer xerror.Resp(func(err xerror.XErr) { + fmt.Println(err.Stack()) + }) + xerror.Panic(a2(1, 2, 4, 5)) } func TestTry(t *testing.T) { @@ -56,18 +36,20 @@ func TestTry(t *testing.T) { func BenchmarkPanic(b *testing.B) { for i := 0; i < b.N; i++ { - init21(1, 2, 3) + _ = func() (err error) { + defer xerror.RespErr(&err) + xerror.PanicF(errs.ErrBadRequest, "测试Panic") + return + }() } } func BenchmarkNoPanic(b *testing.B) { for i := 0; i < b.N; i++ { - func() { - defer xerror.Resp(func(_err xerror.XErr) { - _err.Error() - }) - - xerror.PanicF(nil, "hello") + _ = func() (err error) { + defer xerror.RespErr(&err) + xerror.PanicF(nil, "测试NoPanic") + return }() } }