-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.go
67 lines (55 loc) · 1.05 KB
/
errors.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
64
65
66
67
package panicea
import "fmt"
func Trap(fn func()) (reErr error) {
defer catch(&reErr, nil)
fn()
return nil
}
func Try[T any](fn func() T) (val T, reErr error) {
defer catch(&reErr, nil)
return fn(), nil
}
func catch(cause *error, handler func(error)) {
if caught := recover(); caught != nil {
if err, ok := caught.(error); ok {
*cause = err
if handler != nil {
handler(err)
}
} else {
// propagate the original panic up
panic(caught)
}
}
}
type Result[T any] struct {
err error
val T
}
func (r *Result[T]) Throw(args ...interface{}) T {
if r.err == nil {
return r.val
}
if len(args) == 1 {
switch arg := args[0].(type) {
case string:
panic(fmt.Errorf(arg, r.err))
case error:
panic(arg)
case func(error) error:
panic(arg(r.err))
}
}
if len(args) >= 2 {
switch arg0 := args[0].(type) {
case func(error, ...interface{}) error:
panic(arg0(r.err, args[1:]...))
}
}
panic(fmt.Errorf("unexpected args: %v", args))
}
func Catch[T any](val T, err error) *Result[T] {
return &Result[T]{
err, val,
}
}