github.com/Finschia/finschia-sdk@v0.48.1/types/errors/abci_test.go (about) 1 package errors 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/suite" 10 ) 11 12 type abciTestSuite struct { 13 suite.Suite 14 } 15 16 func TestABCITestSuite(t *testing.T) { 17 suite.Run(t, new(abciTestSuite)) 18 } 19 20 func (s *abciTestSuite) SetupSuite() { 21 s.T().Parallel() 22 } 23 24 func (s *abciTestSuite) TestABCInfo() { 25 cases := map[string]struct { 26 err error 27 debug bool 28 wantCode uint32 29 wantSpace string 30 wantLog string 31 }{ 32 "plain SDK error": { 33 err: ErrUnauthorized, 34 debug: false, 35 wantLog: "unauthorized", 36 wantCode: ErrUnauthorized.code, 37 wantSpace: RootCodespace, 38 }, 39 "wrapped SDK error": { 40 err: Wrap(Wrap(ErrUnauthorized, "foo"), "bar"), 41 debug: false, 42 wantLog: "bar: foo: unauthorized", 43 wantCode: ErrUnauthorized.code, 44 wantSpace: RootCodespace, 45 }, 46 "nil is empty message": { 47 err: nil, 48 debug: false, 49 wantLog: "", 50 wantCode: 0, 51 wantSpace: "", 52 }, 53 "nil SDK error is not an error": { 54 err: (*Error)(nil), 55 debug: false, 56 wantLog: "", 57 wantCode: 0, 58 wantSpace: "", 59 }, 60 "stdlib returns error message in debug mode": { 61 err: io.EOF, 62 debug: true, 63 wantLog: "EOF", 64 wantCode: 1, 65 wantSpace: UndefinedCodespace, 66 }, 67 // This is hard to test because of attached stacktrace. This 68 // case is tested in an another test. 69 //"wrapped stdlib is a full message in debug mode": { 70 // err: Wrap(io.EOF, "cannot read file"), 71 // debug: true, 72 // wantLog: "cannot read file: EOF", 73 // wantCode: 1, 74 //}, 75 "custom error": { 76 err: customErr{}, 77 debug: false, 78 wantLog: "custom", 79 wantCode: 999, 80 wantSpace: "extern", 81 }, 82 "custom error in debug mode": { 83 err: customErr{}, 84 debug: true, 85 wantLog: "custom", 86 wantCode: 999, 87 wantSpace: "extern", 88 }, 89 } 90 91 for testName, tc := range cases { 92 s.T().Run(testName, func(t *testing.T) { 93 space, code, log := ABCIInfo(tc.err, tc.debug) 94 s.Require().Equal(tc.wantSpace, space, testName) 95 s.Require().Equal(tc.wantCode, code, testName) 96 s.Require().Equal(tc.wantLog, log, testName) 97 }) 98 } 99 } 100 101 func (s *abciTestSuite) TestABCIInfoStacktrace() { 102 cases := map[string]struct { 103 err error 104 debug bool 105 wantStacktrace bool 106 wantErrMsg string 107 }{ 108 "wrapped SDK error in debug mode provides stacktrace": { 109 err: Wrap(ErrUnauthorized, "wrapped"), 110 debug: true, 111 wantStacktrace: true, 112 wantErrMsg: "wrapped: unauthorized", 113 }, 114 "wrapped SDK error in non-debug mode does not have stacktrace": { 115 err: Wrap(ErrUnauthorized, "wrapped"), 116 debug: false, 117 wantStacktrace: false, 118 wantErrMsg: "wrapped: unauthorized", 119 }, 120 "wrapped stdlib error in debug mode provides stacktrace": { 121 err: Wrap(fmt.Errorf("stdlib"), "wrapped"), 122 debug: true, 123 wantStacktrace: true, 124 wantErrMsg: "wrapped: stdlib", 125 }, 126 } 127 128 const thisTestSrc = "github.com/Finschia/finschia-sdk/types/errors.(*abciTestSuite).TestABCIInfoStacktrace" 129 130 for testName, tc := range cases { 131 s.T().Run(testName, func(t *testing.T) { 132 _, _, log := ABCIInfo(tc.err, tc.debug) 133 if !tc.wantStacktrace { 134 s.Require().Equal(tc.wantErrMsg, log, testName) 135 } else { 136 s.Require().True(strings.Contains(log, thisTestSrc), testName) 137 s.Require().True(strings.Contains(log, tc.wantErrMsg), testName) 138 } 139 }) 140 } 141 } 142 143 func (s *abciTestSuite) TestABCIInfoHidesStacktrace() { 144 err := Wrap(ErrUnauthorized, "wrapped") 145 _, _, log := ABCIInfo(err, false) 146 s.Require().Equal("wrapped: unauthorized", log) 147 } 148 149 func (s *abciTestSuite) TestABCIInfoSerializeErr() { 150 var ( 151 // Create errors with stacktrace for equal comparison. 152 myErrDecode = Wrap(ErrTxDecode, "test") 153 myErrAddr = Wrap(ErrInvalidAddress, "tester") 154 myPanic = ErrPanic 155 ) 156 157 specs := map[string]struct { 158 src error 159 debug bool 160 exp string 161 }{ 162 "single error": { 163 src: myErrDecode, 164 debug: false, 165 exp: "test: tx parse error", 166 }, 167 "second error": { 168 src: myErrAddr, 169 debug: false, 170 exp: "tester: invalid address", 171 }, 172 "single error with debug": { 173 src: myErrDecode, 174 debug: true, 175 exp: fmt.Sprintf("%+v", myErrDecode), 176 }, 177 "do not redact in debug encoder": { 178 src: myPanic, 179 debug: true, 180 exp: fmt.Sprintf("%+v", myPanic), 181 }, 182 } 183 for msg, spec := range specs { 184 spec := spec 185 _, _, log := ABCIInfo(spec.src, spec.debug) 186 s.Require().Equal(spec.exp, log, msg) 187 } 188 } 189 190 func (s *abciTestSuite) TestQueryResultWithDebug() { 191 q := QueryResultWithDebug(Wrap(errInternal, "test error"), true) 192 s.Require().Equal(q.Code, uint32(1)) 193 s.Require().Equal(q.Codespace, "undefined") 194 } 195 196 // customErr is a custom implementation of an error that provides an ABCICode 197 // method. 198 type customErr struct{} 199 200 func (customErr) Codespace() string { return "extern" } 201 202 func (customErr) ABCICode() uint32 { return 999 } 203 204 func (customErr) Error() string { return "custom" }