diff --git a/src/internal/error/errors.go b/src/internal/error/errors.go index 7b61f3618..38e72487b 100644 --- a/src/internal/error/errors.go +++ b/src/internal/error/errors.go @@ -32,6 +32,12 @@ func (e *Error) WithCode(code string) *Error { return e } +// WithCause ... +func (e *Error) WithCause(err error) *Error { + e.Cause = err + return e +} + // Unwrap ... func (e *Error) Unwrap() error { return e.Cause } @@ -101,18 +107,52 @@ const ( ) // New ... -func New(err error) *Error { - e := &Error{} - if err != nil { - e.Cause = err - e.Message = err.Error() - if ee, ok := err.(*Error); ok { - e.Cause = ee - } +func New(in interface{}) *Error { + var err error + switch in := in.(type) { + case error: + err = in + case *Error: + err = in.Cause + default: + err = fmt.Errorf("%v", in) + } + return &Error{ + Cause: err, + Message: err.Error(), + } +} + +// Wrap ... +func Wrap(err error, message string) *Error { + if err == nil { + return nil + } + e := &Error{ + Cause: err, + Message: message, } return e } +// Wrapf ... +func Wrapf(err error, format string, args ...interface{}) *Error { + if err == nil { + return nil + } + e := &Error{ + Cause: err, + } + return e.WithMessage(format, args...) +} + +// Errorf ... +func Errorf(format string, args ...interface{}) *Error { + return &Error{ + Message: fmt.Sprintf(format, args...), + } +} + // NotFoundError is error for the case of object not found func NotFoundError(err error) *Error { return New(err).WithCode(NotFoundCode).WithMessage("resource not found") @@ -153,6 +193,18 @@ func UnknownError(err error) *Error { return New(err).WithCode(GeneralCode).WithMessage("unknown") } +// Cause gets the root error +func Cause(err error) error { + for err != nil { + cause, ok := err.(*Error) + if !ok { + break + } + err = cause.Cause + } + return err +} + // IsErr checks whether the err chain contains error matches the code func IsErr(err error, code string) bool { var e *Error