-
Notifications
You must be signed in to change notification settings - Fork 174
Expand file tree
/
Copy pathutils.go
More file actions
91 lines (81 loc) · 2.3 KB
/
utils.go
File metadata and controls
91 lines (81 loc) · 2.3 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package errox
import (
"fmt"
"net"
"net/url"
"strings"
"github.com/pkg/errors"
)
// IsAny returns a bool if it matches any of the target errors
// This helps consolidate code from
// errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.ErrClosedPipe)
// to errors.IsAny(err, io.EOF. io.ErrUnexpectedEOF, io.ErrClosedPipe)
func IsAny(err error, targets ...error) bool {
for _, target := range targets {
if errors.Is(err, target) {
return true
}
}
return false
}
type multipleErrors interface{ Unwrap() []error }
// wrapErrors is a copy from the standard errors package:
// https://cs.opensource.google/go/go/+/refs/tags/go1.22.6:src/fmt/errors.go;l=67
type wrapErrors struct {
msg string
errs []error
}
func (e *wrapErrors) Error() string {
return e.msg
}
func (e *wrapErrors) Unwrap() []error {
return e.errs
}
var _ multipleErrors = (*wrapErrors)(nil)
func concealMultiple(errs multipleErrors) error {
unwrapped := errs.Unwrap()
concealed := make([]error, 0, len(unwrapped))
msg := make([]string, 0, len(unwrapped))
for _, e := range unwrapped {
e = ConcealSensitive(e)
concealed = append(concealed, e)
msg = append(msg, e.Error())
}
return &wrapErrors{
msg: fmt.Sprintf("[%s]", strings.Join(msg, ", ")),
errs: concealed,
}
}
// ConcealSensitive strips sensitive data from some known error types and
// returns a new error if something has been concealed, and otherwise the
// original error is returned.
func ConcealSensitive(err error) error {
original := err
for err != nil {
// Here are reimplementations of the *.Error() methods of the original
// errors, without including potentially sensitive data to the message.
switch e := err.(type) {
case *net.AddrError:
return errors.New("address error: " + e.Err)
case *net.DNSError:
return errors.New("lookup error: " + e.Err)
case *net.OpError:
s := e.Op
if e.Net != "" {
s += " " + e.Net
}
if e.Err != nil {
s += ": " + ConcealSensitive(e.Err).Error()
}
return errors.New(s)
case *url.Error:
return errors.New(fmt.Sprintf("%s %q: %s", e.Op, e.URL, ConcealSensitive(e.Err)))
}
// multipleErrors can be returned by fmt.Errorf() with multiple %w.
if errs, ok := err.(multipleErrors); ok {
return concealMultiple(errs)
}
err = errors.Unwrap(err)
}
return original
}