panictoerr.gno
1.42 Kb ยท 62 lines
1package panictoerr
2
3import (
4 "errors"
5
6 "gno.land/p/nt/ufmt"
7)
8
9// PanicToError executes a function that might panic and, if it does,
10// recovers the panic and converts it to an error.
11func PanicToError(mightPanic func()) (err error) {
12 // Catch any panic that might occur and convert it to an error.
13 defer func() {
14 if r := recover(); r != nil {
15 err = anyToError(r)
16 }
17 }()
18
19 // Execute the function that might panic.
20 mightPanic()
21
22 return nil
23}
24
25// AbortToError executes a function that might abort, and if it does,
26// revives the abort and converts it to an error.
27func AbortToError(mightAbort func()) error {
28 // Catch any abort that might occur and convert it to an error.
29 if r := revive(mightAbort); r != nil {
30 return anyToError(r)
31 }
32
33 return nil
34}
35
36// PanicAbortToError executes a function that might either panic or abort,
37// and if it does, it recovers the panic or revives the abort and converts
38// it to an error.
39func PanicAbortToError(mightPanicOrAbort func()) error {
40 var panicErr error
41
42 // Catch any panic or abort that might occur and convert it to an error.
43 if abortErr := AbortToError(func() {
44 panicErr = PanicToError(mightPanicOrAbort)
45 }); abortErr != nil {
46 return abortErr
47 }
48
49 return panicErr
50}
51
52// anyToError converts any value to an error.
53func anyToError(v any) error {
54 switch v := v.(type) {
55 case string:
56 return errors.New(v)
57 case error:
58 return v
59 default:
60 return errors.New(ufmt.Sprint(v))
61 }
62}