From f5515e50669353e4fa85bfc1e13868949e202aa4 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Mon, 8 Jan 2018 15:04:31 -0500 Subject: [PATCH 1/5] init From 8b2b5a6bff78d83b85e3d1204800564b5a7e4f96 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Mon, 8 Jan 2018 15:13:07 -0500 Subject: [PATCH 2/5] errors --- .gitignore | 2 ++ Gopkg.lock | 15 +++++++++++++++ Gopkg.toml | 3 +++ README.md | 4 ++++ errors.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 .gitignore create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml create mode 100644 README.md create mode 100644 errors.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f417e74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea +/vendor diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..07b0186 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,15 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/go-errors/errors" + packages = ["."] + revision = "3afebba5a48dbc89b574d890b6b34d9ee10b4785" + version = "v1.0.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "cdb8112723180cdbe98df0e74827b04930f26759f6c08fe39066835774c18175" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..5dc9c30 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,3 @@ +[[constraint]] + name = "github.com/go-errors/errors" + version = "1.0.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..a71fa09 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# errors + +Better error handling. Marries [go-errors/errors](https://github.com/go-errors/errors) to [pkg/errors](https://github.com/pkg/errors), and +adds a little bit of our own magic sauce. \ No newline at end of file diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..c0020d1 --- /dev/null +++ b/errors.go @@ -0,0 +1,48 @@ +package errors + +import ( + "fmt" + + "github.com/go-errors/errors" +) + +// Err intelligently creates/handles errors, while preserving the stack trace. +// It works with errors from github.com/pkg/errors too. +func Err(err interface{}, fmtParams ...interface{}) error { + if err == nil { + return nil + } + + type causer interface { + Cause() error + } + + if _, ok := err.(causer); ok { + err = fmt.Errorf("%+v", err) + } else if errString, ok := err.(string); ok && len(fmtParams) > 0 { + err = fmt.Errorf(errString, fmtParams...) + } + + return errors.Wrap(err, 1) +} + +// Is compares two wrapped errors to determine if the underlying errors are the same +func Is(e error, original error) bool { + return errors.Is(e, original) +} + +// Prefix prefixes the message of the error with the given string +func Prefix(prefix string, err interface{}) error { + if err == nil { + return nil + } + return errors.WrapPrefix(Err(err), prefix, 0) +} + +// Trace returns the error message and the stack trace +func Trace(err error) string { + if err == nil { + return "" + } + return errors.Wrap(Err(err), 0).ErrorStack() +} From a8fd5b2cbdc58d615cbe86505efbbb789d81dbb6 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Mon, 8 Jan 2018 15:41:35 -0500 Subject: [PATCH 3/5] distinguish between full trace (with message) and just trace --- errors.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/errors.go b/errors.go index c0020d1..8ad2ece 100644 --- a/errors.go +++ b/errors.go @@ -39,8 +39,17 @@ func Prefix(prefix string, err interface{}) error { return errors.WrapPrefix(Err(err), prefix, 0) } -// Trace returns the error message and the stack trace +// Trace returns the stack trace func Trace(err error) string { + if err == nil { + return "" + } + return string(errors.Wrap(Err(err), 0).Stack()) +} + + +// FullTrace returns the error type, message, and stack trace +func FullTrace(err error) string { if err == nil { return "" } From 825e9a1235465d351aea5fe4f9900eca2c70450f Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Mon, 8 Jan 2018 16:05:26 -0500 Subject: [PATCH 4/5] add Wrap(), Base(), HasTrace() --- errors.go | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/errors.go b/errors.go index 8ad2ece..50bd80c 100644 --- a/errors.go +++ b/errors.go @@ -1,11 +1,17 @@ package errors import ( + base "errors" "fmt" "github.com/go-errors/errors" ) +// interop with pkg/errors +type causer interface { + Cause() error +} + // Err intelligently creates/handles errors, while preserving the stack trace. // It works with errors from github.com/pkg/errors too. func Err(err interface{}, fmtParams ...interface{}) error { @@ -13,10 +19,6 @@ func Err(err interface{}, fmtParams ...interface{}) error { return nil } - type causer interface { - Cause() error - } - if _, ok := err.(causer); ok { err = fmt.Errorf("%+v", err) } else if errString, ok := err.(string); ok && len(fmtParams) > 0 { @@ -26,6 +28,19 @@ func Err(err interface{}, fmtParams ...interface{}) error { return errors.Wrap(err, 1) } +// Wrap calls errors.Wrap, in case you want to skip a different amount +func Wrap(err interface{}, skip int) *errors.Error { + if err == nil { + return nil + } + + if _, ok := err.(causer); ok { + err = fmt.Errorf("%+v", err) + } + + return errors.Wrap(err, skip+1) +} + // Is compares two wrapped errors to determine if the underlying errors are the same func Is(e error, original error) bool { return errors.Is(e, original) @@ -44,14 +59,24 @@ func Trace(err error) string { if err == nil { return "" } - return string(errors.Wrap(Err(err), 0).Stack()) + return string(Err(err).(*errors.Error).Stack()) } - // FullTrace returns the error type, message, and stack trace func FullTrace(err error) string { if err == nil { return "" } - return errors.Wrap(Err(err), 0).ErrorStack() + return Err(err).(*errors.Error).ErrorStack() +} + +// Base returns a simple error with no stack trace attached +func Base(text string) error { + return base.New(text) +} + +// HasTrace checks if error has a trace attached +func HasTrace(err error) bool { + _, ok := err.(*errors.Error) + return ok } From dd131cce3d6f9c0b2351537cec85955ebc0be5e0 Mon Sep 17 00:00:00 2001 From: Alex Grintsvayg Date: Wed, 7 Feb 2018 09:58:49 -0500 Subject: [PATCH 5/5] make Is() interop with pkg/errors --- errors.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/errors.go b/errors.go index 50bd80c..aae4e04 100644 --- a/errors.go +++ b/errors.go @@ -42,7 +42,14 @@ func Wrap(err interface{}, skip int) *errors.Error { } // Is compares two wrapped errors to determine if the underlying errors are the same +// It also interops with errors from pkg/errors func Is(e error, original error) bool { + if c, ok := e.(causer); ok { + e = c.Cause() + } + if c, ok := original.(causer); ok { + original = c.Cause() + } return errors.Is(e, original) }