-
Notifications
You must be signed in to change notification settings - Fork 1
/
recover-invocation-panic.go
63 lines (50 loc) · 1.52 KB
/
recover-invocation-panic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
© 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"errors"
"github.com/haraldrudell/parl/perrors"
)
// RecoverInvocationPanic is intended to wrap callback invocations in the callee in order to
// recover from panics in the callback function.
// when an error occurs, perrors.AppendError appends the callback error to *errp.
// if fn is nil, a recovered panic results.
// if errp is nil, a panic is thrown, can be check with:
//
// if errors.Is(err, parl.ErrNilValue) …
func RecoverInvocationPanic(fn func(), errp *error) {
if errp == nil {
panic(perrors.ErrorfPF("%w", ErrErrpNil))
}
defer Recover(Annotation(), errp, NoOnError)
fn()
}
// ErrErrpNil indicates that a function with an error pointer argument
// received an errp nil value.
//
// if errors.Is(err, parl.ErrNilValue) …
var ErrErrpNil = NilValueError(errors.New("errp cannot be nil"))
func RecoverInvocationPanicErr(fn func() (err error)) (isPanic bool, err error) {
defer Recover(Annotation(), &err, NoOnError)
isPanic = true
err = fn()
isPanic = false
return
}
type TFunc[T any] func() (value T, err error)
type TResult[T any] struct {
Value T
IsPanic bool
Err error
}
// RecoverInvocationPanicT invokes resolver, recover panics and populates v
func NewTResult[T any](tFunc TFunc[T]) (tResult *TResult[T]) {
var t = TResult[T]{IsPanic: true}
tResult = &t
defer Recover(Annotation(), &t.Err, NoOnError)
t.Value, t.Err = tFunc()
t.IsPanic = false
return
}