-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
67 lines (53 loc) · 1.24 KB
/
errors.go
File metadata and controls
67 lines (53 loc) · 1.24 KB
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 taskgroup
import (
"errors"
"fmt"
"slices"
)
// ErrPanic is the sentinel that wraps every panic recovered by the package.
// Test with errors.Is(err, taskgroup.ErrPanic) to detect a recovered panic.
var ErrPanic = errors.New("panic")
type taskResult struct {
err error
panic bool
}
// Named return lets the deferred recover set result on panic.
//
//nolint:nonamedreturns
func recoverTask(fn func() error) (result taskResult) {
defer func() {
if pc := recover(); pc != nil {
result.err = panicToError(pc)
result.panic = true
}
}()
result.err = fn()
return result
}
func recoverError(fn func() error) (err error) {
defer func() {
if pc := recover(); pc != nil {
err = panicToError(pc)
}
}()
return fn()
}
func panicToError(pc any) error {
if err, ok := pc.(error); ok {
return fmt.Errorf("%w: %w", ErrPanic, err)
}
return fmt.Errorf("%w: %v", ErrPanic, pc)
}
func joinErrors(primary error, errGroups ...[]error) error {
var errs []error
if primary != nil {
errs = append(errs, primary)
}
for _, group := range errGroups {
errs = append(errs, group...)
}
return errors.Join(errs...)
}
func compactErrors(errs []error) []error {
return slices.DeleteFunc(errs, func(err error) bool { return err == nil })
}