package errors import "fmt" type withCode struct { err error code int cause error *stack } func WithCode(code int, format string, args ...interface{}) error { return &withCode{ err: fmt.Errorf(format, args...), code: code, stack: callers(), } } func Wrap(err error, message string) error { if err == nil { return nil } if e, ok := err.(*withCode); ok { return &withCode{ err: fmt.Errorf(message), code: e.code, cause: err, stack: callers(), } } return &withCode{ err: fmt.Errorf(message), code: unknownCoder.Code(), cause: err, stack: callers(), } } func WrapC(err error, code int, format string, args ...interface{}) error { if err == nil { return nil } return &withCode{ err: fmt.Errorf(format, args...), code: code, cause: err, stack: callers(), } } func (w *withCode) Error() string { return fmt.Sprintf("%v", w) } // Cause 返回根因 func (w *withCode) Cause() error { return w.cause } // Unwrap 返回根因 func (w *withCode) Unwrap() error { return w.cause } func Cause(err error) error { type causer interface { Cause() error } for err != nil { cause, ok := err.(causer) if !ok { break } if cause.Cause() == nil { break } err = cause.Cause() } return err }