-
Notifications
You must be signed in to change notification settings - Fork 0
/
try.go
159 lines (138 loc) · 4.49 KB
/
try.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package try
import (
"errors"
"fmt"
)
// Try0 is a wrapper for a function that returns an error
func Try0(err error) {
if err != nil {
panic(err)
}
}
// Try1 is a wrapper for a function that returns a value and an error
func Try1[T any](value T, err error) T {
if err != nil {
panic(err)
}
return value
}
// Try2 is a wrapper for a function that returns two values and an error
func Try2[T1 any, T2 any](value1 T1, value2 T2, err error) (T1, T2) {
if err != nil {
panic(err)
}
return value1, value2
}
// Try3 is a wrapper for a function that returns three values and an error
func Try3[T1 any, T2 any, T3 any](value1 T1, value2 T2, value3 T3, err error) (T1, T2, T3) {
if err != nil {
panic(err)
}
return value1, value2, value3
}
// Try4 is a wrapper for a function that returns four values and an error
func Try4[T1 any, T2 any, T3 any, T4 any](value1 T1, value2 T2, value3 T3, value4 T4, err error) (T1, T2, T3, T4) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4
}
// Try5 is a wrapper for a function that returns five values and an error
func Try5[T1 any, T2 any, T3 any, T4 any, T5 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, err error) (T1, T2, T3, T4, T5) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5
}
// Try6 is a wrapper for a function that returns six values and an error
func Try6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, value6 T6, err error) (T1, T2, T3, T4, T5, T6) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5, value6
}
// Try7 is a wrapper for a function that returns seven values and an error
func Try7[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, value6 T6, value7 T7, err error) (T1, T2, T3, T4, T5, T6, T7) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5, value6, value7
}
// Try8 is a wrapper for a function that returns eight values and an error
func Try8[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, value6 T6, value7 T7, value8 T8, err error) (T1, T2, T3, T4, T5, T6, T7, T8) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5, value6, value7, value8
}
// Try9 is a wrapper for a function that returns nine values and an error
func Try9[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, value6 T6, value7 T7, value8 T8, value9 T9, err error) (T1, T2, T3, T4, T5, T6, T7, T8, T9) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5, value6, value7, value8, value9
}
// Try10 is a wrapper for a function that returns ten values and an error
func Try10[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any, T7 any, T8 any, T9 any, T10 any](value1 T1, value2 T2, value3 T3, value4 T4, value5 T5, value6 T6, value7 T7, value8 T8, value9 T9, value10 T10, err error) (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
if err != nil {
panic(err)
}
return value1, value2, value3, value4, value5, value6, value7, value8, value9, value10
}
type tryCatchFinally struct {
tryCatch
}
type tryCatch struct {
finally func()
err error
}
// Try tries to execute the functions. If any of the functions returns an error,
// the error will be caught and passed to the catch function.
func Try(functions ...func()) (result tryCatchFinally) {
defer func() {
if r := recover(); r != nil {
if v, ok := r.(error); ok {
result.err = v
return
}
result.err = fmt.Errorf("%v", r)
}
}()
for _, function := range functions {
function()
}
return result
}
// CatchMap is a map of errors and their corresponding catch functions.
type CatchMap map[error]func(error)
type anyError struct{}
// AnyError is an error that can be used to catch any error.
var AnyError = anyError{}
func (a anyError) Error() string {
return "any error"
}
// Catch catches the error and executes the corresponding catch function.
func (t tryCatch) Catch(catchMap CatchMap) {
defer func() {
if t.finally != nil {
t.finally()
}
}()
if t.err != nil {
for k, v := range catchMap {
if errors.Is(t.err, k) {
v(t.err)
return
}
}
if v, ok := catchMap[AnyError]; ok {
v(t.err)
return
}
}
}
// Finally executes the final function.
func (t tryCatchFinally) Finally(finally func()) tryCatch {
t.tryCatch.finally = finally
return t.tryCatch
}