Refactor errors package, so we can do type-checking IsXXErr()

This commit is contained in:
Ethan Frey
2017-07-03 14:22:46 +02:00
parent 2fc4da1076
commit 5fa77bf647
4 changed files with 200 additions and 49 deletions
+31
View File
@@ -19,6 +19,10 @@ type stackTracer interface {
StackTrace() errors.StackTrace
}
type causer interface {
Cause() error
}
type TMError interface {
stackTracer
ErrorCode() abci.CodeType
@@ -31,6 +35,11 @@ type tmerror struct {
msg string
}
var (
_ causer = tmerror{}
_ error = tmerror{}
)
func (t tmerror) ErrorCode() abci.CodeType {
return t.code
}
@@ -39,6 +48,13 @@ func (t tmerror) Message() string {
return t.msg
}
func (t tmerror) Cause() error {
if c, ok := t.stackTracer.(causer); ok {
return c.Cause()
}
return t.stackTracer
}
// Format handles "%+v" to expose the full stack trace
// concept from pkg/errors
func (t tmerror) Format(s fmt.State, verb rune) {
@@ -102,3 +118,18 @@ func New(msg string, code abci.CodeType) TMError {
msg: msg,
}
}
// IsSameError returns true if these errors have the same root cause.
// pattern is the expected error type and should always be non-nil
// err may be anything and returns true if it is a wrapped version of pattern
func IsSameError(pattern error, err error) bool {
return err != nil && (errors.Cause(err) == errors.Cause(pattern))
}
// HasErrorCode checks if this error would return the named error code
func HasErrorCode(err error, code abci.CodeType) bool {
if tm, ok := err.(TMError); ok {
return tm.ErrorCode() == code
}
return code == defaultErrCode
}