4
4
"errors"
5
5
"fmt"
6
6
"testing"
7
+ "time"
7
8
8
9
"github.com/stretchr/testify/require"
9
10
)
@@ -29,8 +30,7 @@ func TestPanicErrorx(t *testing.T) {
29
30
output := fmt .Sprintf ("%v" , r )
30
31
31
32
require .Contains (t , output , "awful" , output )
32
- // original error was non-errorx, no use of adding panic callstack to message
33
- require .NotContains (t , output , "errorx.funcWithBadPanic()" , output )
33
+ require .Contains (t , output , "errorx.funcWithBadPanic()" , output )
34
34
}()
35
35
36
36
funcWithBadPanic ()
@@ -111,3 +111,69 @@ func funcWithBadPanic() {
111
111
func funcWithBadErr () error {
112
112
return errors .New ("awful" )
113
113
}
114
+
115
+ func TestPanicChain (t * testing.T ) {
116
+ ch0 := make (chan error , 1 )
117
+ ch1 := make (chan error , 1 )
118
+
119
+ go doMischief (ch1 )
120
+ go doMoreMischief (ch0 , ch1 )
121
+
122
+ select {
123
+ case err := <- ch0 :
124
+ require .Error (t , err )
125
+ require .False (t , IsOfType (err , AssertionFailed ))
126
+ output := fmt .Sprintf ("%+v" , err )
127
+ require .Contains (t , output , "mischiefProper" , output )
128
+ require .Contains (t , output , "mischiefAsPanic" , output )
129
+ require .Contains (t , output , "doMischief" , output )
130
+ require .Contains (t , output , "handleMischief" , output )
131
+ require .NotContains (t , output , "doMoreMischief" , output ) // stack trace is only enhanced in Panic, not in user code
132
+ t .Log (output )
133
+ case <- time .After (time .Second ):
134
+ require .Fail (t , "expected error" )
135
+ }
136
+ }
137
+
138
+ func doMoreMischief (ch0 chan error , ch1 chan error ) {
139
+ defer func () {
140
+ if e := recover (); e != nil {
141
+ err , ok := ErrorFromPanic (e )
142
+ if ok {
143
+ ch0 <- Decorate (err , "hop 2" )
144
+ return
145
+ }
146
+ }
147
+ ch0 <- AssertionFailed .New ("test failed" )
148
+ }()
149
+
150
+ handleMischief (ch1 )
151
+ }
152
+
153
+ func handleMischief (ch chan error ) {
154
+ err := <- ch
155
+ Panic (Decorate (err , "handle" ))
156
+ }
157
+
158
+ func doMischief (ch chan error ) {
159
+ defer func () {
160
+ if e := recover (); e != nil {
161
+ err , ok := ErrorFromPanic (e )
162
+ if ok {
163
+ ch <- Decorate (err , "hop 1" )
164
+ return
165
+ }
166
+ }
167
+ ch <- AssertionFailed .New ("test failed" )
168
+ }()
169
+
170
+ mischiefAsPanic ()
171
+ }
172
+
173
+ func mischiefAsPanic () {
174
+ Panic (mischiefProper ())
175
+ }
176
+
177
+ func mischiefProper () error {
178
+ return ExternalError .New ("mischief" )
179
+ }
0 commit comments