forked from rbaliyan/config
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
306 lines (244 loc) · 9.24 KB
/
errors.go
File metadata and controls
306 lines (244 loc) · 9.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
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
package config
import (
"errors"
"fmt"
)
// Sentinel errors for config operations.
// Use errors.Is() to check for these errors as they may be wrapped.
var (
// ErrNotFound is returned when a config key does not exist.
ErrNotFound = errors.New("config: key not found")
// ErrTypeMismatch is returned when attempting to convert a value to an incompatible type.
ErrTypeMismatch = errors.New("config: type mismatch")
// ErrInvalidKey is returned when a config key is empty or malformed.
ErrInvalidKey = errors.New("config: invalid key")
// ErrInvalidNamespace is returned when a namespace is malformed.
ErrInvalidNamespace = errors.New("config: invalid namespace")
// ErrInvalidValue is returned when a value cannot be stored.
ErrInvalidValue = errors.New("config: invalid value")
// ErrStoreNotConnected is returned when operating on a disconnected store.
ErrStoreNotConnected = errors.New("config: store not connected")
// ErrStoreClosed is returned when operating on a closed store.
ErrStoreClosed = errors.New("config: store closed")
// ErrWatchNotSupported is returned when the store does not support watching.
ErrWatchNotSupported = errors.New("config: watch not supported")
// ErrManagerClosed is returned when operating on a closed manager.
ErrManagerClosed = errors.New("config: manager closed")
// ErrCodecNotFound is returned when a codec is not registered.
ErrCodecNotFound = errors.New("config: codec not found")
// ErrReadOnly is returned when attempting to write to a read-only store.
ErrReadOnly = errors.New("config: store is read-only")
// ErrKeyExists is returned when attempting to create a key that already exists.
ErrKeyExists = errors.New("config: key already exists")
// ErrUnsupportedCodec is returned when a store does not support the requested codec.
ErrUnsupportedCodec = errors.New("config: unsupported codec")
// ErrVersionNotFound is returned when a specific version of a key does not exist.
ErrVersionNotFound = errors.New("config: version not found")
// ErrVersioningNotSupported is returned when the store does not support versioning.
ErrVersioningNotSupported = errors.New("config: versioning not supported")
// ErrNamespaceFull is returned when a namespace has reached its maximum key count.
ErrNamespaceFull = errors.New("config: namespace key limit exceeded")
)
// KeyNotFoundError provides details about a missing key.
type KeyNotFoundError struct {
Key string
Namespace string
}
func (e *KeyNotFoundError) Error() string {
if e.Namespace != "" {
return fmt.Sprintf("config: key %q not found in namespace %q", e.Key, e.Namespace)
}
return fmt.Sprintf("config: key %q not found", e.Key)
}
func (e *KeyNotFoundError) Unwrap() error {
return ErrNotFound
}
// IsNotFound checks if an error indicates a missing key.
func IsNotFound(err error) bool {
return errors.Is(err, ErrNotFound)
}
// TypeMismatchError provides details about a type conversion failure.
type TypeMismatchError struct {
Key string
Expected Type
Actual Type
}
func (e *TypeMismatchError) Error() string {
return fmt.Sprintf("config: key %q has type %s, cannot convert to %s", e.Key, e.Actual, e.Expected)
}
func (e *TypeMismatchError) Unwrap() error {
return ErrTypeMismatch
}
// IsTypeMismatch checks if an error indicates a type mismatch.
func IsTypeMismatch(err error) bool {
return errors.Is(err, ErrTypeMismatch)
}
// InvalidKeyError provides details about an invalid key.
type InvalidKeyError struct {
Key string
Reason string
}
func (e *InvalidKeyError) Error() string {
return fmt.Sprintf("config: invalid key %q: %s", e.Key, e.Reason)
}
func (e *InvalidKeyError) Unwrap() error {
return ErrInvalidKey
}
// IsInvalidKey checks if an error indicates an invalid key.
func IsInvalidKey(err error) bool {
return errors.Is(err, ErrInvalidKey)
}
// StoreError wraps backend-specific errors with domain context.
type StoreError struct {
Op string // Operation that failed
Key string // Key involved (if applicable)
Backend string // Backend name (memory, mongodb, postgres)
Err error // Underlying error
}
func (e *StoreError) Error() string {
if e.Key != "" {
return fmt.Sprintf("config: %s [%s] key=%q: %v", e.Op, e.Backend, e.Key, e.Err)
}
return fmt.Sprintf("config: %s [%s]: %v", e.Op, e.Backend, e.Err)
}
func (e *StoreError) Unwrap() error {
return e.Err
}
// WrapStoreError creates a StoreError from a backend error.
func WrapStoreError(op, backend, key string, err error) error {
if err == nil {
return nil
}
// Don't double-wrap
var se *StoreError
if errors.As(err, &se) {
return err
}
return &StoreError{Op: op, Backend: backend, Key: key, Err: err}
}
// KeyExistsError provides details about a key that already exists.
type KeyExistsError struct {
Key string
Namespace string
}
func (e *KeyExistsError) Error() string {
if e.Namespace != "" {
return fmt.Sprintf("config: key %q already exists in namespace %q", e.Key, e.Namespace)
}
return fmt.Sprintf("config: key %q already exists", e.Key)
}
func (e *KeyExistsError) Unwrap() error {
return ErrKeyExists
}
// IsKeyExists checks if an error indicates a key already exists.
func IsKeyExists(err error) bool {
return errors.Is(err, ErrKeyExists)
}
// UnsupportedCodecError provides details about a codec that is not supported by the store.
type UnsupportedCodecError struct {
Codec string
Backend string
}
func (e *UnsupportedCodecError) Error() string {
return fmt.Sprintf("config: codec %q is not supported by backend %q", e.Codec, e.Backend)
}
func (e *UnsupportedCodecError) Unwrap() error {
return ErrUnsupportedCodec
}
// IsUnsupportedCodec checks if an error indicates an unsupported codec.
func IsUnsupportedCodec(err error) bool {
return errors.Is(err, ErrUnsupportedCodec)
}
// ErrWatchUnhealthy is returned by Health() when watch has consecutive failures.
var ErrWatchUnhealthy = errors.New("config: watch unhealthy")
// WatchHealthError provides details about watch connection failures.
// Returned by Manager.Health() when watch has multiple consecutive failures.
type WatchHealthError struct {
ConsecutiveFailures int32
LastError string
}
func (e *WatchHealthError) Error() string {
if e.LastError != "" {
return fmt.Sprintf("config: watch unhealthy (%d consecutive failures): %s", e.ConsecutiveFailures, e.LastError)
}
return fmt.Sprintf("config: watch unhealthy (%d consecutive failures)", e.ConsecutiveFailures)
}
func (e *WatchHealthError) Unwrap() error {
return ErrWatchUnhealthy
}
// IsWatchUnhealthy checks if an error indicates watch connection issues.
func IsWatchUnhealthy(err error) bool {
return errors.Is(err, ErrWatchUnhealthy)
}
// ErrBulkWritePartial is returned when a bulk write operation partially fails.
var ErrBulkWritePartial = errors.New("config: bulk write partially failed")
// BulkWriteError provides details about partial failures in bulk operations.
// Use KeyErrors() to see which keys failed and which succeeded.
type BulkWriteError struct {
// Errors maps keys to their specific errors. Only failed keys are included.
Errors map[string]error
// Succeeded contains keys that were written successfully.
Succeeded []string
}
func (e *BulkWriteError) Error() string {
return fmt.Sprintf("config: bulk write partially failed: %d succeeded, %d failed",
len(e.Succeeded), len(e.Errors))
}
func (e *BulkWriteError) Unwrap() error {
return ErrBulkWritePartial
}
// KeyErrors returns the map of key -> error for failed keys.
func (e *BulkWriteError) KeyErrors() map[string]error {
return e.Errors
}
// FailedKeys returns the list of keys that failed.
func (e *BulkWriteError) FailedKeys() []string {
keys := make([]string, 0, len(e.Errors))
for k := range e.Errors {
keys = append(keys, k)
}
return keys
}
// IsBulkWritePartial checks if an error indicates a partial bulk write failure.
// Use errors.As() to get the BulkWriteError for details about which keys failed.
func IsBulkWritePartial(err error) bool {
return errors.Is(err, ErrBulkWritePartial)
}
// VersionNotFoundError provides details about a missing version.
type VersionNotFoundError struct {
Key string
Namespace string
Version int64
}
func (e *VersionNotFoundError) Error() string {
if e.Namespace != "" {
return fmt.Sprintf("config: version %d of key %q not found in namespace %q", e.Version, e.Key, e.Namespace)
}
return fmt.Sprintf("config: version %d of key %q not found", e.Version, e.Key)
}
func (e *VersionNotFoundError) Unwrap() error {
return ErrVersionNotFound
}
// IsVersionNotFound checks if an error indicates a missing version.
func IsVersionNotFound(err error) bool {
return errors.Is(err, ErrVersionNotFound)
}
// IsVersioningNotSupported checks if an error indicates versioning is not supported.
func IsVersioningNotSupported(err error) bool {
return errors.Is(err, ErrVersioningNotSupported)
}
// NamespaceFullError provides details about a namespace that has reached its key limit.
type NamespaceFullError struct {
Namespace string
Limit int
}
func (e *NamespaceFullError) Error() string {
return fmt.Sprintf("config: namespace %q has reached its key limit of %d", e.Namespace, e.Limit)
}
func (e *NamespaceFullError) Unwrap() error {
return ErrNamespaceFull
}
// IsNamespaceFull checks if an error indicates a namespace has reached its key limit.
func IsNamespaceFull(err error) bool {
return errors.Is(err, ErrNamespaceFull)
}