3333 (no special treatment; they'll hit `CatchAll` blocks and `Finally` blocks;
3434 it would of course be silly for them to hit `Catch` blocks since those
3535 use spacemonkey-errors types). Panics with values that are not of golang's
36- `error` type at all will trigger `Finally` blocks but otherwise
37- be immediately repanicked.
36+ `error` type at all will be wrapped in a spacemonkey error for the purpose
37+ of handling (as an interface design, `CatchAll(interface{})` is unpleasant).
38+ See `OriginalError` and `Repanic` for more invormation on handling these
39+ wrapped panic objects.
3840
3941 A `try.Do(func() {...})` with no attached errors handlers is legal but
4042 pointless. A `try.Do(func() {...})` with no `Done()` will never run the
6163 UnknownPanicError = errors .NewClass ("Unknown Error" )
6264
6365 // The spacemonkey error key to get the original data out of an UnknownPanicError.
64- OriginalPanic = errors .GenSym ()
66+ OriginalErrorKey = errors .GenSym ()
6567)
6668
6769type Plan struct {
@@ -153,14 +155,14 @@ func (p *Plan) Done() {
153155 if catch .match == nil {
154156 consumed = true
155157 msg := fmt .Sprintf ("%v" , rec )
156- pan := UnknownPanicError .NewWith (msg , errors .SetData (OriginalPanic , rec ))
158+ pan := UnknownPanicError .NewWith (msg , errors .SetData (OriginalErrorKey , rec ))
157159 catch .anyhandler (pan )
158160 return
159161 }
160162 if UnknownPanicError .Is (catch .match ) {
161163 consumed = true
162164 msg := fmt .Sprintf ("%v" , rec )
163- pan := UnknownPanicError .NewWith (msg , errors .SetData (OriginalPanic , rec ))
165+ pan := UnknownPanicError .NewWith (msg , errors .SetData (OriginalErrorKey , rec ))
164166 catch .handler (pan .(* errors.Error ))
165167 return
166168 }
@@ -170,9 +172,26 @@ func (p *Plan) Done() {
170172 p .main ()
171173}
172174
175+ /*
176+ If `err` was originally another value coerced to an error by `CatchAll`,
177+ this will return the original value. Otherwise, it returns the same error
178+ again.
179+
180+ See also `Repanic()`.
181+ */
182+ func OriginalError (err error ) interface {} {
183+ data := errors .GetData (err , OriginalErrorKey )
184+ if data == nil {
185+ return err
186+ }
187+ return data
188+ }
189+
173190/*
174191 Panics again with the original error.
175192
193+ Shorthand, equivalent to calling `panic(OriginalError(err))`
194+
176195 If the error is a `UnknownPanicError` (i.e., a `CatchAll` block that's handling something
177196 that wasn't originally an `error` type, so it was wrapped), it will unwrap that re-panic
178197 with that original error -- in other words, this is a "do the right thing" method in all scenarios.
@@ -192,9 +211,9 @@ func Repanic(err error) {
192211 if ! wrapper .Is (UnknownPanicError ) {
193212 panic (err )
194213 }
195- data := errors .GetData (err , OriginalPanic )
214+ data := errors .GetData (err , OriginalErrorKey )
196215 if data == nil {
197- panic (errors .ProgrammerError .New ("misuse of try internals" , errors .SetData (OriginalPanic , err )))
216+ panic (errors .ProgrammerError .New ("misuse of try internals" , errors .SetData (OriginalErrorKey , err )))
198217 }
199218 panic (data )
200219}
0 commit comments