errors cleanup

This commit is contained in:
rigel rozanski 2017-07-19 01:23:13 -04:00
parent 0a9460dc93
commit 8617841296
18 changed files with 214 additions and 119 deletions

View File

@ -29,7 +29,7 @@ test_unit:
test_cli: tests/cli/shunit2
# sudo apt-get install jq
./tests/cli/keys.sh
#./tests/cli/rpc.sh
./tests/cli/rpc.sh
./tests/cli/init.sh
./tests/cli/basictx.sh
./tests/cli/counter.sh

View File

@ -5,27 +5,17 @@ import (
"fmt"
"reflect"
"github.com/pkg/errors"
abci "github.com/tendermint/abci/types"
)
var (
errDecoding = fmt.Errorf("Error decoding input")
errUnauthorized = fmt.Errorf("Unauthorized")
errInvalidSignature = fmt.Errorf("Invalid Signature")
errTooLarge = fmt.Errorf("Input size too large")
errNoSigners = fmt.Errorf("There are no signers")
errMissingSignature = fmt.Errorf("Signature missing")
errTooManySignatures = fmt.Errorf("Too many signatures")
errNoChain = fmt.Errorf("No chain id provided")
errTxEmpty = fmt.Errorf("The provided Tx is empty")
errWrongChain = fmt.Errorf("Wrong chain for tx")
errUnknownTxType = fmt.Errorf("Tx type unknown")
errInvalidFormat = fmt.Errorf("Invalid format")
errUnknownModule = fmt.Errorf("Unknown module")
errExpired = fmt.Errorf("Tx expired")
errUnknownKey = fmt.Errorf("Unknown key")
errDecoding = fmt.Errorf("Error decoding input")
errUnauthorized = fmt.Errorf("Unauthorized")
errTooLarge = fmt.Errorf("Input size too large")
errMissingSignature = fmt.Errorf("Signature missing")
errUnknownTxType = fmt.Errorf("Tx type unknown")
errInvalidFormat = fmt.Errorf("Invalid format")
errUnknownModule = fmt.Errorf("Unknown module")
internalErr = abci.CodeType_InternalError
encodingErr = abci.CodeType_EncodingError
@ -70,14 +60,6 @@ func IsUnknownModuleErr(err error) bool {
return IsSameError(errUnknownModule, err)
}
func ErrUnknownKey(mod string) TMError {
w := errors.Wrap(errUnknownKey, mod)
return WithCode(w, abci.CodeType_UnknownRequest)
}
func IsUnknownKeyErr(err error) bool {
return IsSameError(errUnknownKey, err)
}
func ErrInternal(msg string) TMError {
return New(msg, internalErr)
}
@ -104,10 +86,6 @@ func IsUnauthorizedErr(err error) bool {
return HasErrorCode(err, unauthorized)
}
func ErrNoSigners() TMError {
return WithCode(errNoSigners, unauthorized)
}
func ErrMissingSignature() TMError {
return WithCode(errMissingSignature, unauthorized)
}
@ -115,49 +93,9 @@ func IsMissingSignatureErr(err error) bool {
return IsSameError(errMissingSignature, err)
}
func ErrTooManySignatures() TMError {
return WithCode(errTooManySignatures, unauthorized)
}
func IsTooManySignaturesErr(err error) bool {
return IsSameError(errTooManySignatures, err)
}
func ErrInvalidSignature() TMError {
return WithCode(errInvalidSignature, unauthorized)
}
func IsInvalidSignatureErr(err error) bool {
return IsSameError(errInvalidSignature, err)
}
func ErrNoChain() TMError {
return WithCode(errNoChain, unauthorized)
}
func IsNoChainErr(err error) bool {
return IsSameError(errNoChain, err)
}
func ErrTxEmpty() TMError {
return WithCode(errTxEmpty, unauthorized)
}
func ErrWrongChain(chain string) TMError {
msg := errors.Wrap(errWrongChain, chain)
return WithCode(msg, unauthorized)
}
func IsWrongChainErr(err error) bool {
return IsSameError(errWrongChain, err)
}
func ErrTooLarge() TMError {
return WithCode(errTooLarge, encodingErr)
}
func IsTooLargeErr(err error) bool {
return IsSameError(errTooLarge, err)
}
func ErrExpired() TMError {
return WithCode(errExpired, unauthorized)
}
func IsExpiredErr(err error) bool {
return IsSameError(errExpired, err)
}

View File

@ -42,7 +42,6 @@ func TestErrorMatches(t *testing.T) {
{errUnauthorized, ErrUnauthorized(), true},
{errMissingSignature, ErrUnauthorized(), false},
{errMissingSignature, ErrMissingSignature(), true},
{errWrongChain, ErrWrongChain("hakz"), true},
{errUnknownTxType, ErrUnknownTxType(holder{}), true},
{errUnknownTxType, ErrUnknownTxType("some text here..."), true},
{errUnknownTxType, ErrUnknownTxType(demoTx{5}.Wrap()), true},
@ -66,13 +65,6 @@ func TestChecks(t *testing.T) {
{ErrDecoding(), IsDecodingErr, true},
{ErrUnauthorized(), IsDecodingErr, false},
{ErrUnauthorized(), IsUnauthorizedErr, true},
{ErrInvalidSignature(), IsInvalidSignatureErr, true},
// unauthorized includes InvalidSignature, but not visa versa
{ErrInvalidSignature(), IsUnauthorizedErr, true},
{ErrUnauthorized(), IsInvalidSignatureErr, false},
// make sure WrongChain works properly
{ErrWrongChain("fooz"), IsUnauthorizedErr, true},
{ErrWrongChain("barz"), IsWrongChainErr, true},
// make sure lots of things match InternalErr, but not everything
{ErrInternal("bad db connection"), IsInternalErr, true},
{Wrap(errors.New("wrapped")), IsInternalErr, true},

30
modules/auth/errors.go Normal file
View File

@ -0,0 +1,30 @@
//nolint
package auth
import (
"fmt"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/errors"
)
var (
errInvalidSignature = fmt.Errorf("Invalid Signature") //move auth
errTooManySignatures = fmt.Errorf("Too many signatures") //move auth
unauthorized = abci.CodeType_Unauthorized
)
func ErrTooManySignatures() errors.TMError {
return errors.WithCode(errTooManySignatures, unauthorized)
}
func IsTooManySignaturesErr(err error) bool {
return errors.IsSameError(errTooManySignatures, err)
}
func ErrInvalidSignature() errors.TMError {
return errors.WithCode(errInvalidSignature, unauthorized)
}
func IsInvalidSignatureErr(err error) bool {
return errors.IsSameError(errInvalidSignature, err)
}

View File

@ -0,0 +1,29 @@
package auth
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/basecoin/errors"
)
func TestChecks(t *testing.T) {
// TODO: make sure the Is and Err methods match
assert := assert.New(t)
cases := []struct {
err error
check func(error) bool
match bool
}{
// unauthorized includes InvalidSignature, but not visa versa
{ErrInvalidSignature(), IsInvalidSignatureErr, true},
{ErrInvalidSignature(), errors.IsUnauthorizedErr, true},
}
for i, tc := range cases {
match := tc.check(tc.err)
assert.Equal(tc.match, match, "%d", i)
}
}

View File

@ -106,7 +106,7 @@ func (s *OneSig) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
return errors.ErrMissingSignature()
}
if !s.Empty() {
return errors.ErrTooManySignatures()
return ErrTooManySignatures()
}
// set the value once we are happy
s.Signed = signed
@ -121,7 +121,7 @@ func (s *OneSig) Signers() ([]crypto.PubKey, error) {
return nil, errors.ErrMissingSignature()
}
if !s.Pubkey.VerifyBytes(s.SignBytes(), s.Sig) {
return nil, errors.ErrInvalidSignature()
return nil, ErrInvalidSignature()
}
return []crypto.PubKey{s.Pubkey}, nil
}
@ -194,7 +194,7 @@ func (s *MultiSig) Signers() ([]crypto.PubKey, error) {
for i := range s.Sigs {
ms := s.Sigs[i]
if !ms.Pubkey.VerifyBytes(data, ms.Sig) {
return nil, errors.ErrInvalidSignature()
return nil, ErrInvalidSignature()
}
keys[i] = ms.Pubkey
}

View File

@ -2,7 +2,6 @@ package base
import (
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/stack"
"github.com/tendermint/basecoin/state"
)
@ -48,7 +47,7 @@ func (c Chain) checkChainTx(chainID string, height uint64, tx basecoin.Tx) (base
// make sure it is a chaintx
ctx, ok := tx.Unwrap().(ChainTx)
if !ok {
return tx, errors.ErrNoChain()
return tx, ErrNoChain()
}
// basic validation
@ -59,10 +58,10 @@ func (c Chain) checkChainTx(chainID string, height uint64, tx basecoin.Tx) (base
// compare against state
if ctx.ChainID != chainID {
return tx, errors.ErrWrongChain(ctx.ChainID)
return tx, ErrWrongChain(ctx.ChainID)
}
if ctx.ExpiresAt != 0 && ctx.ExpiresAt <= height {
return tx, errors.ErrExpired()
return tx, ErrExpired()
}
return ctx.Tx, nil
}

40
modules/base/errors.go Normal file
View File

@ -0,0 +1,40 @@
//nolint
package base
import (
"fmt"
pkgerrors "github.com/pkg/errors"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/errors"
)
var (
errNoChain = fmt.Errorf("No chain id provided") //move base
errWrongChain = fmt.Errorf("Wrong chain for tx") //move base
errExpired = fmt.Errorf("Tx expired") //move base
unauthorized = abci.CodeType_Unauthorized
)
func ErrNoChain() errors.TMError {
return errors.WithCode(errNoChain, unauthorized)
}
func IsNoChainErr(err error) bool {
return errors.IsSameError(errNoChain, err)
}
func ErrWrongChain(chain string) errors.TMError {
msg := pkgerrors.Wrap(errWrongChain, chain)
return errors.WithCode(msg, unauthorized)
}
func IsWrongChainErr(err error) bool {
return errors.IsSameError(errWrongChain, err)
}
func ErrExpired() errors.TMError {
return errors.WithCode(errExpired, unauthorized)
}
func IsExpiredErr(err error) bool {
return errors.IsSameError(errExpired, err)
}

View File

@ -0,0 +1,45 @@
package base
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/basecoin/errors"
)
func TestErrorMatches(t *testing.T) {
assert := assert.New(t)
cases := []struct {
pattern, err error
match bool
}{
{errWrongChain, ErrWrongChain("hakz"), true},
}
for i, tc := range cases {
same := errors.IsSameError(tc.pattern, tc.err)
assert.Equal(tc.match, same, "%d: %#v / %#v", i, tc.pattern, tc.err)
}
}
func TestChecks(t *testing.T) {
// TODO: make sure the Is and Err methods match
assert := assert.New(t)
cases := []struct {
err error
check func(error) bool
match bool
}{
// make sure WrongChain works properly
{ErrWrongChain("fooz"), errors.IsUnauthorizedErr, true},
{ErrWrongChain("barz"), IsWrongChainErr, true},
}
for i, tc := range cases {
match := tc.check(tc.err)
assert.Equal(tc.match, match, "%d", i)
}
}

View File

@ -86,10 +86,10 @@ func (c ChainTx) Wrap() basecoin.Tx {
}
func (c ChainTx) ValidateBasic() error {
if c.ChainID == "" {
return errors.ErrNoChain()
return ErrNoChain()
}
if !chainPattern.MatchString(c.ChainID) {
return errors.ErrWrongChain(c.ChainID)
return ErrWrongChain(c.ChainID)
}
if c.Tx.Empty() {
return errors.ErrUnknownTxType(c.Tx)

View File

@ -4,9 +4,9 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
lc "github.com/tendermint/light-client"
lcmd "github.com/tendermint/basecoin/client/commands"
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
lc "github.com/tendermint/light-client"
"github.com/tendermint/basecoin/modules/auth"
"github.com/tendermint/basecoin/modules/coin"
@ -17,10 +17,10 @@ import (
var AccountQueryCmd = &cobra.Command{
Use: "account [address]",
Short: "Get details of an account, with proof",
RunE: lcmd.RequireInit(doAccountQuery),
RunE: lcmd.RequireInit(accountQueryCmd),
}
func doAccountQuery(cmd *cobra.Command, args []string) error {
func accountQueryCmd(cmd *cobra.Command, args []string) error {
addr, err := proofcmd.ParseHexKey(args, "address")
if err != nil {
return err

View File

@ -14,7 +14,7 @@ import (
var SendTxCmd = &cobra.Command{
Use: "send",
Short: "send tokens from one account to another",
RunE: commands.RequireInit(doSendTx),
RunE: commands.RequireInit(sendTxCmd),
}
//nolint
@ -31,8 +31,8 @@ func init() {
flags.String(FlagFrom, "", "Address sending coins, if not first signer")
}
// doSendTx is an example of how to make a tx
func doSendTx(cmd *cobra.Command, args []string) error {
// sendTxCmd is an example of how to make a tx
func sendTxCmd(cmd *cobra.Command, args []string) error {
// load data from json or flags
// var tx basecoin.Tx
// found, err := txcmd.LoadJSON(&tx)

View File

@ -4,23 +4,25 @@ package coin
import (
"fmt"
pkgerrors "github.com/pkg/errors"
abci "github.com/tendermint/abci/types"
"github.com/tendermint/basecoin/errors"
)
var (
errNoAccount = fmt.Errorf("No such account")
errInsufficientFunds = fmt.Errorf("Insufficient Funds")
errNoInputs = fmt.Errorf("No Input Coins")
errNoOutputs = fmt.Errorf("No Output Coins")
errInvalidAddress = fmt.Errorf("Invalid Address")
errInvalidCoins = fmt.Errorf("Invalid Coins")
)
errInsufficientFunds = fmt.Errorf("Insufficient funds")
errNoInputs = fmt.Errorf("No input coins")
errNoOutputs = fmt.Errorf("No output coins")
errInvalidAddress = fmt.Errorf("Invalid address")
errInvalidCoins = fmt.Errorf("Invalid coins")
errUnknownKey = fmt.Errorf("Unknown key")
var (
invalidInput = abci.CodeType_BaseInvalidInput
invalidOutput = abci.CodeType_BaseInvalidOutput
unknownAddress = abci.CodeType_BaseUnknownAddress
unknownRequest = abci.CodeType_UnknownRequest
)
// here are some generic handlers to grab classes of errors based on code
@ -79,3 +81,11 @@ func ErrNoOutputs() errors.TMError {
func IsNoOutputsErr(err error) bool {
return errors.IsSameError(errNoOutputs, err)
}
func ErrUnknownKey(mod string) errors.TMError {
w := pkgerrors.Wrap(errUnknownKey, mod)
return errors.WithCode(w, unknownRequest)
}
func IsUnknownKeyErr(err error) bool {
return errors.IsSameError(errUnknownKey, err)
}

View File

@ -99,7 +99,7 @@ func (h Handler) SetOption(l log.Logger, store state.KVStore, module, key, value
return "Success", nil
}
return "", errors.ErrUnknownKey(key)
return "", ErrUnknownKey(key)
}
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {

View File

@ -10,19 +10,21 @@ import (
)
var (
errInsufficientFees = fmt.Errorf("Insufficient Fees")
errInsufficientFees = fmt.Errorf("Insufficient fees")
errWrongFeeDenom = fmt.Errorf("Required fee denomination")
invalidInput = abci.CodeType_BaseInvalidInput
)
func ErrInsufficientFees() errors.TMError {
return errors.WithCode(errInsufficientFees, abci.CodeType_BaseInvalidInput)
return errors.WithCode(errInsufficientFees, invalidInput)
}
func IsInsufficientFeesErr(err error) bool {
return errors.IsSameError(errInsufficientFees, err)
}
func ErrWrongFeeDenom(denom string) errors.TMError {
return errors.WithMessage(denom, errWrongFeeDenom, abci.CodeType_BaseInvalidInput)
return errors.WithMessage(denom, errWrongFeeDenom, invalidInput)
}
func IsWrongFeeDenomErr(err error) bool {
return errors.IsSameError(errWrongFeeDenom, err)

View File

@ -11,22 +11,31 @@ import (
var (
errNoNonce = fmt.Errorf("Tx doesn't contain nonce")
errNotMember = fmt.Errorf("nonce contains non-permissioned member")
errNotMember = fmt.Errorf("Nonce contains non-permissioned member")
errZeroSequence = fmt.Errorf("Sequence number cannot be zero")
errNoSigners = fmt.Errorf("There are no signers")
errTxEmpty = fmt.Errorf("The provided Tx is empty")
unauthorized = abci.CodeType_Unauthorized
badNonce = abci.CodeType_BadNonce
invalidInput = abci.CodeType_BaseInvalidInput
)
func ErrBadNonce(got, expected uint32) errors.TMError {
return errors.WithCode(fmt.Errorf("Bad nonce sequence, got %d, expected %d", got, expected), unauthorized)
return errors.WithCode(fmt.Errorf("Bad nonce sequence, got %d, expected %d", got, expected), badNonce)
}
func ErrNoNonce() errors.TMError {
return errors.WithCode(errNoNonce, unauthorized)
return errors.WithCode(errNoNonce, badNonce)
}
func ErrNotMember() errors.TMError {
return errors.WithCode(errNotMember, unauthorized)
}
func ErrZeroSequence() errors.TMError {
return errors.WithCode(errZeroSequence, unauthorized)
return errors.WithCode(errZeroSequence, invalidInput)
}
func ErrNoSigners() errors.TMError {
return errors.WithCode(errNoSigners, invalidInput)
}
func ErrTxEmpty() errors.TMError {
return errors.WithCode(errTxEmpty, invalidInput)
}

View File

@ -11,7 +11,6 @@ import (
"sort"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/state"
)
@ -50,11 +49,11 @@ func (n Tx) Wrap() basecoin.Tx {
func (n Tx) ValidateBasic() error {
switch {
case n.Tx.Empty():
return errors.ErrTxEmpty()
return ErrTxEmpty()
case n.Sequence == 0:
return ErrZeroSequence()
case len(n.Signers) == 0:
return errors.ErrNoSigners()
return ErrNoSigners()
}
return n.Tx.ValidateBasic()
}

View File

@ -16,54 +16,56 @@ var (
errNoMembers = fmt.Errorf("No members specified")
errTooManyMembers = fmt.Errorf("Too many members specified")
errNotEnoughMembers = fmt.Errorf("Not enough members specified")
unauthorized = abci.CodeType_Unauthorized
)
// TODO: codegen?
// ex: err-gen NoRole,"No such role",CodeType_Unauthorized
func ErrNoRole() errors.TMError {
return errors.WithCode(errNoRole, abci.CodeType_Unauthorized)
return errors.WithCode(errNoRole, unauthorized)
}
func IsNoRoleErr(err error) bool {
return errors.IsSameError(errNoRole, err)
}
func ErrRoleExists() errors.TMError {
return errors.WithCode(errRoleExists, abci.CodeType_Unauthorized)
return errors.WithCode(errRoleExists, unauthorized)
}
func IsRoleExistsErr(err error) bool {
return errors.IsSameError(errRoleExists, err)
}
func ErrNotMember() errors.TMError {
return errors.WithCode(errNotMember, abci.CodeType_Unauthorized)
return errors.WithCode(errNotMember, unauthorized)
}
func IsNotMemberErr(err error) bool {
return errors.IsSameError(errNotMember, err)
}
func ErrInsufficientSigs() errors.TMError {
return errors.WithCode(errInsufficientSigs, abci.CodeType_Unauthorized)
return errors.WithCode(errInsufficientSigs, unauthorized)
}
func IsInsufficientSigsErr(err error) bool {
return errors.IsSameError(errInsufficientSigs, err)
}
func ErrNoMembers() errors.TMError {
return errors.WithCode(errNoMembers, abci.CodeType_Unauthorized)
return errors.WithCode(errNoMembers, unauthorized)
}
func IsNoMembersErr(err error) bool {
return errors.IsSameError(errNoMembers, err)
}
func ErrTooManyMembers() errors.TMError {
return errors.WithCode(errTooManyMembers, abci.CodeType_Unauthorized)
return errors.WithCode(errTooManyMembers, unauthorized)
}
func IsTooManyMembersErr(err error) bool {
return errors.IsSameError(errTooManyMembers, err)
}
func ErrNotEnoughMembers() errors.TMError {
return errors.WithCode(errNotEnoughMembers, abci.CodeType_Unauthorized)
return errors.WithCode(errNotEnoughMembers, unauthorized)
}
func IsNotEnoughMembersErr(err error) bool {
return errors.IsSameError(errNotEnoughMembers, err)