From a1c14399e923fd0be0ab8a2ac64a36c259ffda6d Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Wed, 18 Dec 2019 12:12:51 -0500 Subject: [PATCH] Remove old error types and logic --- types/errors_old/errors.go | 361 -------------------------------- types/errors_old/errors_test.go | 138 ------------ 2 files changed, 499 deletions(-) delete mode 100644 types/errors_old/errors.go delete mode 100644 types/errors_old/errors_test.go diff --git a/types/errors_old/errors.go b/types/errors_old/errors.go deleted file mode 100644 index dd7aca5ea8f3..000000000000 --- a/types/errors_old/errors.go +++ /dev/null @@ -1,361 +0,0 @@ -package errors_old - -import ( - "bytes" - "encoding/json" - "fmt" - "strings" - - "github.com/pkg/errors" - - abci "github.com/tendermint/tendermint/abci/types" - cmn "github.com/tendermint/tendermint/libs/common" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// CodeType - ABCI code identifier within codespace -type CodeType uint32 - -// CodespaceType - codespace identifier -type CodespaceType string - -// IsOK - is everything okay? -func (code CodeType) IsOK() bool { - return code == CodeOK -} - -// SDK error codes -const ( - // Base error codes - CodeOK CodeType = 0 - CodeInternal CodeType = 1 - CodeTxDecode CodeType = 2 - CodeInvalidSequence CodeType = 3 - CodeUnauthorized CodeType = 4 - CodeInsufficientFunds CodeType = 5 - CodeUnknownRequest CodeType = 6 - CodeInvalidAddress CodeType = 7 - CodeInvalidPubKey CodeType = 8 - CodeUnknownAddress CodeType = 9 - CodeInsufficientCoins CodeType = 10 - CodeInvalidCoins CodeType = 11 - CodeOutOfGas CodeType = 12 - CodeMemoTooLarge CodeType = 13 - CodeInsufficientFee CodeType = 14 - CodeTooManySignatures CodeType = 15 - CodeGasOverflow CodeType = 16 - CodeNoSignatures CodeType = 17 - CodeTxInMempoolCache CodeType = 18 - CodeMempoolIsFull CodeType = 19 - CodeTxTooLarge CodeType = 20 - - // CodespaceRoot is a codespace for error codes in this file only. - // Notice that 0 is an "unset" codespace, which can be overridden with - // Error.WithDefaultCodespace(). - CodespaceUndefined CodespaceType = "" - CodespaceRoot CodespaceType = "sdk" -) - -func unknownCodeMsg(code CodeType) string { - return fmt.Sprintf("unknown code %d", code) -} - -// NOTE: Don't stringer this, we'll put better messages in later. -func CodeToDefaultMsg(code CodeType) string { - switch code { - case CodeInternal: - return "internal error" - case CodeTxDecode: - return "tx parse error" - case CodeInvalidSequence: - return "invalid sequence" - case CodeUnauthorized: - return "unauthorized" - case CodeInsufficientFunds: - return "insufficient funds" - case CodeUnknownRequest: - return "unknown request" - case CodeInvalidAddress: - return "invalid address" - case CodeInvalidPubKey: - return "invalid pubkey" - case CodeUnknownAddress: - return "unknown address" - case CodeInsufficientCoins: - return "insufficient coins" - case CodeInvalidCoins: - return "invalid coins" - case CodeOutOfGas: - return "out of gas" - case CodeMemoTooLarge: - return "memo too large" - case CodeInsufficientFee: - return "insufficient fee" - case CodeTooManySignatures: - return "maximum numer of signatures exceeded" - case CodeNoSignatures: - return "no signatures supplied" - default: - return unknownCodeMsg(code) - } -} - -//-------------------------------------------------------------------------------- -// All errors are created via constructors so as to enable us to hijack them -// and inject stack traces if we really want to. - -// nolint -func ErrInternal(msg string) Error { - return newErrorWithRootCodespace(CodeInternal, msg) -} -func ErrTxDecode(msg string) Error { - return newErrorWithRootCodespace(CodeTxDecode, msg) -} -func ErrInvalidSequence(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidSequence, msg) -} -func ErrUnauthorized(msg string) Error { - return newErrorWithRootCodespace(CodeUnauthorized, msg) -} -func ErrInsufficientFunds(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientFunds, msg) -} -func ErrUnknownRequest(msg string) Error { - return newErrorWithRootCodespace(CodeUnknownRequest, msg) -} -func ErrInvalidAddress(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidAddress, msg) -} -func ErrUnknownAddress(msg string) Error { - return newErrorWithRootCodespace(CodeUnknownAddress, msg) -} -func ErrInvalidPubKey(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidPubKey, msg) -} -func ErrInsufficientCoins(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientCoins, msg) -} -func ErrInvalidCoins(msg string) Error { - return newErrorWithRootCodespace(CodeInvalidCoins, msg) -} -func ErrOutOfGas(msg string) Error { - return newErrorWithRootCodespace(CodeOutOfGas, msg) -} -func ErrMemoTooLarge(msg string) Error { - return newErrorWithRootCodespace(CodeMemoTooLarge, msg) -} -func ErrInsufficientFee(msg string) Error { - return newErrorWithRootCodespace(CodeInsufficientFee, msg) -} -func ErrTooManySignatures(msg string) Error { - return newErrorWithRootCodespace(CodeTooManySignatures, msg) -} -func ErrNoSignatures(msg string) Error { - return newErrorWithRootCodespace(CodeNoSignatures, msg) -} -func ErrGasOverflow(msg string) Error { - return newErrorWithRootCodespace(CodeGasOverflow, msg) -} - -//---------------------------------------- -// Error & sdkError - -type cmnError = cmn.Error - -// sdk Error type -type Error interface { - // Implements cmn.Error - // Error() string - // Stacktrace() cmn.Error - // Trace(offset int, format string, args ...interface{}) cmn.Error - // Data() interface{} - cmnError - - // convenience - TraceSDK(format string, args ...interface{}) Error - - // set codespace - WithDefaultCodespace(CodespaceType) Error - - Code() CodeType - Codespace() CodespaceType - ABCILog() string - Result() Result - QueryResult() abci.ResponseQuery -} - -// NewError - create an error. -func NewError(codespace CodespaceType, code CodeType, format string, args ...interface{}) Error { - return newError(codespace, code, format, args...) -} - -func newErrorWithRootCodespace(code CodeType, format string, args ...interface{}) *sdkError { - return newError(CodespaceRoot, code, format, args...) -} - -func newError(codespace CodespaceType, code CodeType, format string, args ...interface{}) *sdkError { - if format == "" { - format = CodeToDefaultMsg(code) - } - return &sdkError{ - codespace: codespace, - code: code, - cmnError: cmn.NewError(format, args...), - } -} - -type sdkError struct { - codespace CodespaceType - code CodeType - cmnError -} - -// Implements Error. -func (err *sdkError) WithDefaultCodespace(cs CodespaceType) Error { - codespace := err.codespace - if codespace == CodespaceUndefined { - codespace = cs - } - return &sdkError{ - codespace: cs, - code: err.code, - cmnError: err.cmnError, - } -} - -// Implements ABCIError. -// nolint: errcheck -func (err *sdkError) TraceSDK(format string, args ...interface{}) Error { - err.Trace(1, format, args...) - return err -} - -// Implements ABCIError. -func (err *sdkError) Error() string { - return fmt.Sprintf(`ERROR: -Codespace: %s -Code: %d -Message: %#v -`, err.codespace, err.code, err.cmnError.Error()) -} - -// Implements Error. -func (err *sdkError) Codespace() CodespaceType { - return err.codespace -} - -// Implements Error. -func (err *sdkError) Code() CodeType { - return err.code -} - -// Implements ABCIError. -func (err *sdkError) ABCILog() string { - errMsg := err.cmnError.Error() - return encodeErrorLog(err.codespace, err.code, errMsg) -} - -func encodeErrorLog(codespace CodespaceType, code CodeType, msg string) string { - jsonErr := humanReadableError{ - Codespace: codespace, - Code: code, - Message: msg, - } - - var buff bytes.Buffer - enc := json.NewEncoder(&buff) - enc.SetEscapeHTML(false) - - if err := enc.Encode(jsonErr); err != nil { - panic(errors.Wrap(err, "failed to encode ABCI error log")) - } - - return strings.TrimSpace(buff.String()) -} - -func (err *sdkError) Result() Result { - return Result{ - Code: err.Code(), - Codespace: err.Codespace(), - Log: err.ABCILog(), - } -} - -// QueryResult allows us to return sdk.Error.QueryResult() in query responses -func (err *sdkError) QueryResult() abci.ResponseQuery { - return abci.ResponseQuery{ - Code: uint32(err.Code()), - Codespace: string(err.Codespace()), - Log: err.ABCILog(), - } -} - -// ResultFromError will return err.Result() if it implements sdk.Error -// Otherwise, it will use the reflecton from types/error to determine -// the code, codespace, and log. -// -// This is intended to provide a bridge to allow both error types -// to live side-by-side. -func ResultFromError(err error) Result { - if sdk, ok := err.(Error); ok { - return sdk.Result() - } - space, code, log := sdkerrors.ABCIInfo(err, false) - return Result{ - Codespace: CodespaceType(space), - Code: CodeType(code), - Log: encodeErrorLog(CodespaceType(space), CodeType(code), log), - } -} - -// ConvertError accepts a standard error and attempts to convert it to an sdk.Error. -// If the given error is already an sdk.Error, it'll simply be returned. Otherwise, -// it'll convert it to a types.Error. This is meant to provide a migration path -// away from sdk.Error in favor of types.Error. -func ConvertError(err error) Error { - if err == nil { - return nil - } - if sdkError, ok := err.(Error); ok { - return sdkError - } - - space, code, log := sdkerrors.ABCIInfo(err, false) - return NewError(CodespaceType(space), CodeType(code), log) -} - -//---------------------------------------- -// REST error utilities - -// appends a message to the head of the given error -func AppendMsgToErr(msg string, err string) string { - msgIdx := strings.Index(err, "message\":\"") - if msgIdx != -1 { - errMsg := err[msgIdx+len("message\":\"") : len(err)-2] - errMsg = fmt.Sprintf("%s; %s", msg, errMsg) - return fmt.Sprintf("%s%s%s", - err[:msgIdx+len("message\":\"")], - errMsg, - err[len(err)-2:], - ) - } - return fmt.Sprintf("%s; %s", msg, err) -} - -// returns the index of the message in the ABCI Log -// nolint:deadcode,unused -func mustGetMsgIndex(abciLog string) int { - msgIdx := strings.Index(abciLog, "message\":\"") - if msgIdx == -1 { - panic(fmt.Sprintf("invalid error format: %s", abciLog)) - } - return msgIdx + len("message\":\"") -} - -// parses the error into an object-like struct for exporting -type humanReadableError struct { - Codespace CodespaceType `json:"codespace"` - Code CodeType `json:"code"` - Message string `json:"message"` -} diff --git a/types/errors_old/errors_test.go b/types/errors_old/errors_test.go deleted file mode 100644 index 24f882862c52..000000000000 --- a/types/errors_old/errors_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package errors_old - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -var codeTypes = []CodeType{ - CodeInternal, - CodeTxDecode, - CodeInvalidSequence, - CodeUnauthorized, - CodeInsufficientFunds, - CodeUnknownRequest, - CodeInvalidAddress, - CodeInvalidPubKey, - CodeUnknownAddress, - CodeInsufficientCoins, - CodeInvalidCoins, - CodeOutOfGas, - CodeMemoTooLarge, -} - -type errFn func(msg string) Error - -var errFns = []errFn{ - ErrInternal, - ErrTxDecode, - ErrInvalidSequence, - ErrUnauthorized, - ErrInsufficientFunds, - ErrUnknownRequest, - ErrInvalidAddress, - ErrInvalidPubKey, - ErrUnknownAddress, - ErrInsufficientCoins, - ErrInvalidCoins, - ErrOutOfGas, - ErrMemoTooLarge, -} - -func TestCodeType(t *testing.T) { - require.True(t, CodeOK.IsOK()) - - for tcnum, c := range codeTypes { - msg := CodeToDefaultMsg(c) - require.NotEqual(t, unknownCodeMsg(c), msg, "Code expected to be known. tc #%d, code %d, msg %s", tcnum, c, msg) - } - - msg := CodeToDefaultMsg(CodeOK) - require.Equal(t, unknownCodeMsg(CodeOK), msg) -} - -func TestErrFn(t *testing.T) { - for i, errFn := range errFns { - err := errFn("") - codeType := codeTypes[i] - require.Equal(t, err.Code(), codeType, "Err function expected to return proper code. tc #%d", i) - require.Equal(t, err.Codespace(), CodespaceRoot, "Err function expected to return proper codespace. tc #%d", i) - require.Equal(t, err.QueryResult().Code, uint32(err.Code()), "Err function expected to return proper Code from QueryResult. tc #%d") - require.Equal(t, err.QueryResult().Log, err.ABCILog(), "Err function expected to return proper ABCILog from QueryResult. tc #%d") - } -} - -func TestAppendMsgToErr(t *testing.T) { - for i, errFn := range errFns { - err := errFn("") - errMsg := err.Stacktrace().Error() - abciLog := err.ABCILog() - - // plain msg error - msg := AppendMsgToErr("something unexpected happened", errMsg) - require.Equal( - t, - fmt.Sprintf("something unexpected happened; %s", errMsg), - msg, - fmt.Sprintf("Should have formatted the error message of ABCI Log. tc #%d", i), - ) - - // ABCI Log msg error - msg = AppendMsgToErr("something unexpected happened", abciLog) - msgIdx := mustGetMsgIndex(abciLog) - require.Equal( - t, - fmt.Sprintf("%s%s; %s}", - abciLog[:msgIdx], - "something unexpected happened", - abciLog[msgIdx:len(abciLog)-1], - ), - msg, - fmt.Sprintf("Should have formatted the error message of ABCI Log. tc #%d", i)) - } -} - -func TestResultFromError(t *testing.T) { - cases := map[string]struct { - err error - expect Result - }{ - "sdk.Error": { - err: ErrUnauthorized("not owner"), - expect: Result{ - Codespace: CodespaceRoot, - Code: CodeUnauthorized, - Log: `{"codespace":"sdk","code":4,"message":"not owner"}`, - }, - }, - "types/errors": { - err: sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "not owner"), - expect: Result{ - Codespace: CodespaceRoot, - Code: CodeUnauthorized, - Log: `{"codespace":"sdk","code":4,"message":"not owner: unauthorized"}`, - }, - }, - "stdlib errors": { - err: fmt.Errorf("not owner"), - expect: Result{ - Codespace: CodespaceType("undefined"), - Code: CodeInternal, - // note that we redact the internal errors in the new package to not leak eg. panics - Log: `{"codespace":"undefined","code":1,"message":"internal error"}`, - }, - }, - } - - for name, tc := range cases { - tc := tc - t.Run(name, func(t *testing.T) { - res := ResultFromError(tc.err) - require.Equal(t, tc.expect, res) - }) - } -}