cosmos-sdk/types/errors/abci_test.go

260 lines
6.3 KiB
Go
Raw Normal View History

package errors
import (
"fmt"
"io"
"strings"
"testing"
"github.com/stretchr/testify/suite"
)
type abciTestSuite struct {
suite.Suite
}
func TestABCITestSuite(t *testing.T) {
suite.Run(t, new(abciTestSuite))
}
func (s *abciTestSuite) SetupSuite() {
s.T().Parallel()
}
func (s *abciTestSuite) TestABCInfo() {
cases := map[string]struct {
err error
debug bool
wantCode uint32
wantSpace string
wantLog string
}{
"plain SDK error": {
err: ErrUnauthorized,
debug: false,
wantLog: "unauthorized",
wantCode: ErrUnauthorized.code,
wantSpace: RootCodespace,
},
"wrapped SDK error": {
err: Wrap(Wrap(ErrUnauthorized, "foo"), "bar"),
debug: false,
wantLog: "bar: foo: unauthorized",
wantCode: ErrUnauthorized.code,
wantSpace: RootCodespace,
},
"nil is empty message": {
err: nil,
debug: false,
wantLog: "",
wantCode: 0,
wantSpace: "",
},
"nil SDK error is not an error": {
err: (*Error)(nil),
debug: false,
wantLog: "",
wantCode: 0,
wantSpace: "",
},
"stdlib is generic message": {
err: io.EOF,
debug: false,
wantLog: "internal",
wantCode: 1,
wantSpace: UndefinedCodespace,
},
"stdlib returns error message in debug mode": {
err: io.EOF,
debug: true,
wantLog: "EOF",
wantCode: 1,
wantSpace: UndefinedCodespace,
},
"wrapped stdlib is only a generic message": {
err: Wrap(io.EOF, "cannot read file"),
debug: false,
wantLog: "internal",
wantCode: 1,
wantSpace: UndefinedCodespace,
},
// This is hard to test because of attached stacktrace. This
// case is tested in an another test.
//"wrapped stdlib is a full message in debug mode": {
// err: Wrap(io.EOF, "cannot read file"),
// debug: true,
// wantLog: "cannot read file: EOF",
// wantCode: 1,
//},
"custom error": {
err: customErr{},
debug: false,
wantLog: "custom",
wantCode: 999,
wantSpace: "extern",
},
"custom error in debug mode": {
err: customErr{},
debug: true,
wantLog: "custom",
wantCode: 999,
wantSpace: "extern",
},
}
for testName, tc := range cases {
space, code, log := ABCIInfo(tc.err, tc.debug)
s.Require().Equal(tc.wantSpace, space, testName)
s.Require().Equal(tc.wantCode, code, testName)
s.Require().Equal(tc.wantLog, log, testName)
}
}
func (s *abciTestSuite) TestABCIInfoStacktrace() {
cases := map[string]struct {
err error
debug bool
wantStacktrace bool
wantErrMsg string
}{
"wrapped SDK error in debug mode provides stacktrace": {
err: Wrap(ErrUnauthorized, "wrapped"),
debug: true,
wantStacktrace: true,
wantErrMsg: "wrapped: unauthorized",
},
"wrapped SDK error in non-debug mode does not have stacktrace": {
err: Wrap(ErrUnauthorized, "wrapped"),
debug: false,
wantStacktrace: false,
wantErrMsg: "wrapped: unauthorized",
},
"wrapped stdlib error in debug mode provides stacktrace": {
err: Wrap(fmt.Errorf("stdlib"), "wrapped"),
debug: true,
wantStacktrace: true,
wantErrMsg: "wrapped: stdlib",
},
"wrapped stdlib error in non-debug mode does not have stacktrace": {
err: Wrap(fmt.Errorf("stdlib"), "wrapped"),
debug: false,
wantStacktrace: false,
wantErrMsg: "internal",
},
}
const thisTestSrc = "github.com/cosmos/cosmos-sdk/types/errors.(*abciTestSuite).TestABCIInfoStacktrace"
for testName, tc := range cases {
_, _, log := ABCIInfo(tc.err, tc.debug)
if !tc.wantStacktrace {
s.Require().Equal(tc.wantErrMsg, log, testName)
continue
}
s.Require().True(strings.Contains(log, thisTestSrc), testName)
s.Require().True(strings.Contains(log, tc.wantErrMsg), testName)
}
}
func (s *abciTestSuite) TestABCIInfoHidesStacktrace() {
err := Wrap(ErrUnauthorized, "wrapped")
_, _, log := ABCIInfo(err, false)
s.Require().Equal("wrapped: unauthorized", log)
}
func (s *abciTestSuite) TestRedact() {
cases := map[string]struct {
err error
untouched bool // if true we expect the same error after redact
changed error // if untouched == false, expect this error
}{
"panic looses message": {
err: Wrap(ErrPanic, "some secret stack trace"),
changed: errPanicWithMsg,
},
"sdk errors untouched": {
err: Wrap(ErrUnauthorized, "cannot drop db"),
untouched: true,
},
"pass though custom errors with ABCI code": {
err: customErr{},
untouched: true,
},
"redact stdlib error": {
err: fmt.Errorf("stdlib error"),
changed: errInternal,
},
}
for name, tc := range cases {
spec := tc
redacted := Redact(spec.err)
if spec.untouched {
s.Require().Equal(spec.err, redacted, name)
continue
}
// see if we got the expected redact
s.Require().Equal(spec.changed, redacted, name)
// make sure the ABCI code did not change
s.Require().Equal(abciCode(spec.err), abciCode(redacted), name)
}
}
func (s *abciTestSuite) TestABCIInfoSerializeErr() {
var (
2019-08-15 06:54:10 -07:00
// Create errors with stacktrace for equal comparison.
myErrDecode = Wrap(ErrTxDecode, "test")
myErrAddr = Wrap(ErrInvalidAddress, "tester")
myPanic = ErrPanic
)
specs := map[string]struct {
src error
debug bool
exp string
}{
"single error": {
src: myErrDecode,
debug: false,
exp: "test: tx parse error",
},
"second error": {
src: myErrAddr,
debug: false,
exp: "tester: invalid address",
},
"single error with debug": {
src: myErrDecode,
debug: true,
exp: fmt.Sprintf("%+v", myErrDecode),
},
"redact in default encoder": {
src: myPanic,
refactor: improve error messages (backport #11762) (#11887) * refactor: improve error messages (#11762) ## Description Closes: #XXXX --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) (cherry picked from commit 8f51644c0ee99148ad82736d9c32028d89c5a040) # Conflicts: # errors/CHANGELOG.md # errors/abci.go * updates * add changelog Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
2022-05-06 06:58:48 -07:00
exp: "error message redacted to hide potential sensitive info. Use the '--trace' flag if you are running a node to see the full stack trace error: panic",
},
"do not redact in debug encoder": {
src: myPanic,
debug: true,
exp: fmt.Sprintf("%+v", myPanic),
},
}
for msg, spec := range specs {
2019-10-17 06:47:35 -07:00
spec := spec
_, _, log := ABCIInfo(spec.src, spec.debug)
s.Require().Equal(spec.exp, log, msg)
}
}
// customErr is a custom implementation of an error that provides an ABCICode
// method.
type customErr struct{}
func (customErr) Codespace() string { return "extern" }
func (customErr) ABCICode() uint32 { return 999 }
func (customErr) Error() string { return "custom" }