From 25e8c8c58b058af548213a895276831bdf0e680e Mon Sep 17 00:00:00 2001 From: charlie <3140647@qq.com> Date: Fri, 13 May 2022 14:07:36 +0800 Subject: [PATCH] error --- errors/error.go | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 errors/error.go diff --git a/errors/error.go b/errors/error.go new file mode 100644 index 0000000..e365d31 --- /dev/null +++ b/errors/error.go @@ -0,0 +1,142 @@ +package errors + +import ( + "errors" + "fmt" + "io" + + stderrors "github.com/pkg/errors" +) + +const ( + defaultErrorCode = "999999" +) + +type CodeError struct { + cause error // 原始错误信息 + code string // 错误码 + message string // 错误消息 +} + +func (e CodeError) Error() string { + if len(e.code) == 0 || e.code == defaultErrorCode { + return e.message + } + + if len(e.message) == 0 { + return fmt.Sprint("err:", e.code) + } + + return fmt.Sprintf("code=%s message=%s", e.code, e.message) +} + +func (e *CodeError) Cause() error { return e.cause } + +func (e *CodeError) Code() string { return e.code } + +func (e *CodeError) Message() string { return e.message } + +func (e *CodeError) Unwrap() error { return stderrors.Unwrap(e.cause) } + +func (e *CodeError) Is(err error) bool { + if se, ok := err.(*CodeError); ok { + return se.code == e.code + } + + return false +} + +func (e *CodeError) As(any) bool { + return false +} + +func (e *CodeError) WithMessage(args ...any) *CodeError { + return new(e.cause, e.code, fmt.Sprint(args...)) +} + +func (e *CodeError) WithMessagef(format string, args ...any) *CodeError { + return new(e.cause, e.code, fmt.Sprintf(format, args...)) +} + +func (e *CodeError) WithCode(code string) *CodeError { + return new(e.cause, code, e.message) +} + +func (e *CodeError) WithStack(err error) *CodeError { + return new(stderrors.WithStack(err), e.code, e.message) +} + +func (e *CodeError) WithCause(err error) *CodeError { + return new(err, e.code, e.message) +} + +func (e *CodeError) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + if e.cause != nil { + fmt.Fprintf(s, "%+v\n", e.Cause()) + } + io.WriteString(s, e.message) + return + } + fallthrough + case 's', 'q': + io.WriteString(s, e.Error()) + } +} + +func new(err error, code string, args ...any) *CodeError { + return &CodeError{ + code: code, + message: fmt.Sprint(args...), + cause: err, + } +} + +func newf(err error, code string, format string, args ...any) *CodeError { + return &CodeError{ + code: code, + message: fmt.Sprintf(format, args...), + cause: err, + } +} + +func Error(code string, args ...any) *CodeError { + return new(nil, code, args...) +} + +func Errorf(code string, format string, args ...any) *CodeError { + return newf(nil, code, format, args...) +} + +func WithStack(err error) error { + return new(stderrors.WithStack(err), defaultErrorCode) +} + +// 附加消息 +func Wrap(err error, code string, args ...any) error { + return new(stderrors.WithStack(err), code, args...) +} + +// 自定义消息并附加堆栈信息 +func Wrapf(err error, code string, format string, args ...any) error { + return newf(stderrors.WithStack(err), code, format, args...) +} + +// 原始错误信息 +func Cause(err error) error { + return stderrors.Unwrap(err) +} + +func Is(err, target error) bool { + return errors.Is(err, target) +} + +func As(err error, target any) bool { + if target == nil { + panic("errors: target cannot be nil") + } + + return errors.As(err, target) +}