2018-01-08 21:13:07 +01:00
|
|
|
package errors
|
|
|
|
|
|
|
|
import (
|
2018-01-08 22:05:26 +01:00
|
|
|
base "errors"
|
2018-01-08 21:13:07 +01:00
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
)
|
|
|
|
|
2018-01-08 22:05:26 +01:00
|
|
|
// interop with pkg/errors
|
|
|
|
type causer interface {
|
|
|
|
Cause() error
|
|
|
|
}
|
|
|
|
|
2018-01-08 21:13:07 +01:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2018-01-08 22:05:26 +01:00
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2018-08-22 18:26:02 +02:00
|
|
|
// Unwrap returns the original error that was wrapped
|
|
|
|
func Unwrap(err error) error {
|
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
deeper := true
|
|
|
|
for deeper {
|
|
|
|
deeper = false
|
|
|
|
if e, ok := err.(*errors.Error); ok {
|
|
|
|
err = e.Err
|
|
|
|
deeper = true
|
|
|
|
}
|
|
|
|
if c, ok := err.(causer); ok {
|
|
|
|
err = c.Cause()
|
|
|
|
deeper = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-01-08 21:13:07 +01:00
|
|
|
// Is compares two wrapped errors to determine if the underlying errors are the same
|
2018-02-07 15:58:49 +01:00
|
|
|
// It also interops with errors from pkg/errors
|
2018-01-08 21:13:07 +01:00
|
|
|
func Is(e error, original error) bool {
|
2018-02-07 15:58:49 +01:00
|
|
|
if c, ok := e.(causer); ok {
|
|
|
|
e = c.Cause()
|
|
|
|
}
|
|
|
|
if c, ok := original.(causer); ok {
|
|
|
|
original = c.Cause()
|
|
|
|
}
|
2018-01-08 21:13:07 +01:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2018-01-08 21:41:35 +01:00
|
|
|
// Trace returns the stack trace
|
2018-01-08 21:13:07 +01:00
|
|
|
func Trace(err error) string {
|
2018-01-08 21:41:35 +01:00
|
|
|
if err == nil {
|
|
|
|
return ""
|
|
|
|
}
|
2018-01-08 22:05:26 +01:00
|
|
|
return string(Err(err).(*errors.Error).Stack())
|
2018-01-08 21:41:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// FullTrace returns the error type, message, and stack trace
|
|
|
|
func FullTrace(err error) string {
|
2018-01-08 21:13:07 +01:00
|
|
|
if err == nil {
|
|
|
|
return ""
|
|
|
|
}
|
2018-01-08 22:05:26 +01:00
|
|
|
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
|
2018-01-08 21:13:07 +01:00
|
|
|
}
|