-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregistry.go
143 lines (121 loc) · 3.43 KB
/
registry.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
package again
import (
"context"
"errors"
"net"
"net/http"
"os"
"sync"
)
// TemporaryError implements the error interface.
type TemporaryError error
// Registry for temporary errors.
type Registry struct {
storage sync.Map // store for temporary errors
}
// NewRegistry creates a new Registry.
func NewRegistry() *Registry {
return &Registry{
storage: sync.Map{},
}
}
// LoadDefaults loads the default temporary errors into the registry.
func (r *Registry) LoadDefaults() *Registry {
// Register default temporary errors.
defaults := map[string]func() TemporaryError{
"os.SyscallError": func() TemporaryError {
return &os.SyscallError{}
},
"context.DeadlineExceededError": func() TemporaryError {
return context.DeadlineExceeded
},
"http.ErrHandlerTimeout": func() TemporaryError {
return http.ErrHandlerTimeout
},
"http.ErrServerClosed": func() TemporaryError {
return http.ErrServerClosed
},
"net.ErrClosed": func() TemporaryError {
return net.ErrClosed
},
"net.ErrWriteToConnected": func() TemporaryError {
return net.ErrWriteToConnected
},
}
// Register default temporary errors.
r.RegisterTemporaryErrors(defaults)
return r
}
// RegisterTemporaryError registers a temporary error.
func (r *Registry) RegisterTemporaryError(name string, fn func() TemporaryError) {
r.storage.Store(name, fn())
}
// RegisterTemporaryErrors registers multiple temporary errors.
func (r *Registry) RegisterTemporaryErrors(temporaryErrors map[string]func() TemporaryError) {
for name, fn := range temporaryErrors {
r.storage.Store(name, fn())
}
}
// UnRegisterTemporaryError unregisters a temporary error(s).
func (r *Registry) UnRegisterTemporaryError(names ...string) {
for _, name := range names {
r.storage.Delete(name)
}
}
// UnRegisterTemporaryErrors unregisters multiple temporary errors.
func (r *Registry) UnRegisterTemporaryErrors(temporaryErrors map[string]func() TemporaryError) {
for name := range temporaryErrors {
r.storage.Delete(name)
}
}
// GetTemporaryError returns a temporary error by name.
func (r *Registry) GetTemporaryError(name string) (TemporaryError, bool) {
tempErr, ok := r.storage.Load(name)
if !ok {
return nil, false
}
return tempErr.(TemporaryError), ok
}
// GetTemporaryErrors returns a list of temporary errors filtered by name.
func (r *Registry) GetTemporaryErrors(names ...string) []TemporaryError {
var errors []TemporaryError
for _, name := range names {
tempErr, ok := r.storage.Load(name)
if !ok {
continue
}
errors = append(errors, tempErr.(TemporaryError))
}
return errors
}
// ListTemporaryErrors returns a list of temporary errors.
func (r *Registry) ListTemporaryErrors() []TemporaryError {
var errors []TemporaryError
r.storage.Range(func(key, value interface{}) bool {
errors = append(errors, value.(TemporaryError))
return true
})
return errors
}
// Clean cleans the Registry.
func (r *Registry) Clean() {
r.storage.Range(func(key, value interface{}) bool {
r.storage.Delete(key)
return true
})
}
// IsTemporaryError checks if the error is in the list of temporary errors.
func (r *Registry) IsTemporaryError(err error, errorsList ...string) bool {
var tempErrors []TemporaryError
if errorsList == nil {
tempErrors = r.ListTemporaryErrors()
} else {
tempErrors = r.GetTemporaryErrors(errorsList...)
}
for _, tempErr := range tempErrors {
if errors.Is(tempErr, err) && err.Error() == tempErr.Error() {
return true
}
}
return false
}