-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy patherrors.go
More file actions
211 lines (172 loc) · 5.91 KB
/
errors.go
File metadata and controls
211 lines (172 loc) · 5.91 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
package amboy
import (
"context"
"fmt"
"github.com/mongodb/grip"
"github.com/pkg/errors"
)
// JobNotFoundError represents an error indicating that a job could not be found
// in a queue.
type JobNotFoundError struct {
msg string
}
// Error returns the error message from the job not found error to provide more
// context as to why the job was not found.
func (e *JobNotFoundError) Error() string { return e.msg }
// NewJobNotFoundError creates a new error indicating that a job could not be
// found in the queue.
func NewJobNotFoundError(msg string) *JobNotFoundError { return &JobNotFoundError{msg: msg} }
// NewJobNotFoundErrorf creates a new error with a formatted message, indicating
// that a job could not be found in the queue.
func NewJobNotFoundErrorf(msg string, args ...interface{}) *JobNotFoundError {
return NewJobNotFoundError(fmt.Sprintf(msg, args...))
}
// MakeJobNotFoundError constructs an error from an existing one, indicating
// that a job could not be found in the queue.
func MakeJobNotFoundError(err error) *JobNotFoundError {
if err == nil {
return nil
}
return NewJobNotFoundError(err.Error())
}
// IsJobNotFound checks if an error was due to not being able to find the job
// in the queue.
func IsJobNotFoundError(err error) bool {
if err == nil {
return false
}
_, ok := errors.Cause(err).(*JobNotFoundError)
return ok
}
// EnqueueUniqueJob is a generic wrapper for adding jobs to queues (using the
// Put() method), but that ignores duplicate job errors.
func EnqueueUniqueJob(ctx context.Context, queue Queue, job Job) error {
err := queue.Put(ctx, job)
if IsDuplicateJobError(err) {
return nil
}
return errors.WithStack(err)
}
// EnqueueManyUniqueJobs is a generic wrapper for adding jobs to a queue (using the
// PutMany() method) ignoring duplicate job errors.
func EnqueueManyUniqueJobs(ctx context.Context, queue Queue, jobs []Job) error {
err := queue.PutMany(ctx, jobs)
if IsDuplicateJobError(err) {
return nil
}
return errors.WithStack(err)
}
// writeErrors contains errors encountered while writing jobs to a queue.
type writeErrors struct {
duplicateJobErrors []error
duplicateScopeErrors []error
otherErrors []error
}
func (w *writeErrors) Error() string {
catcher := grip.NewBasicCatcher()
catcher.Extend(w.duplicateScopeErrors)
catcher.Extend(w.duplicateJobErrors)
catcher.Extend(w.otherErrors)
return catcher.String()
}
// Cause returns the primary cause of the WriteError. The primary cause is defined as follows:
// - If a non-duplicate-job error is encountered a plain error type is returned.
// - If every error is a duplicate job error and at least one of them is a duplicate scope error a duplicate scope error is returned.
// - If every error is a duplicate job error and none of them is a duplicate scope error a duplicate job error is returned.
func (w *writeErrors) Cause() error {
if len(w.otherErrors) > 0 {
catcher := grip.NewBasicCatcher()
catcher.Extend(w.duplicateScopeErrors)
catcher.Extend(w.duplicateJobErrors)
catcher.Extend(w.otherErrors)
return catcher.Resolve()
}
if len(w.duplicateScopeErrors) > 0 {
return MakeDuplicateJobScopeError(w)
}
if len(w.duplicateJobErrors) > 0 {
return MakeDuplicateJobError(w)
}
return nil
}
// CollateWriteErrors collates errors into a [writeErrors].
func CollateWriteErrors(errs []error) error {
if len(errs) == 0 {
return nil
}
var writeErrs writeErrors
for _, err := range errs {
if IsDuplicateJobScopeError(err) {
writeErrs.duplicateScopeErrors = append(writeErrs.duplicateScopeErrors, err)
} else if IsDuplicateJobError(err) {
writeErrs.duplicateJobErrors = append(writeErrs.duplicateJobErrors, err)
} else {
writeErrs.otherErrors = append(writeErrs.otherErrors, err)
}
}
return &writeErrs
}
type duplJobError struct {
msg string
}
func (e *duplJobError) Error() string { return e.msg }
// NewDuplicateJobError creates a new error to represent a duplicate job error,
// for use by queue implementations.
func NewDuplicateJobError(msg string) error { return &duplJobError{msg: msg} }
// NewDuplicateJobErrorf creates a new error to represent a duplicate job error
// with a formatted message, for use by queue implementations.
func NewDuplicateJobErrorf(msg string, args ...interface{}) error {
return NewDuplicateJobError(fmt.Sprintf(msg, args...))
}
// MakeDuplicateJobError constructs a duplicate job error from an existing error
// of any type, for use by queue implementations.
func MakeDuplicateJobError(err error) error {
if err == nil {
return nil
}
return NewDuplicateJobError(err.Error())
}
// IsDuplicateJobError checks if an error is due to a duplicate job in the
// queue.
func IsDuplicateJobError(err error) bool {
if err == nil {
return false
}
switch errors.Cause(err).(type) {
case *duplJobError, *duplJobScopeError:
return true
default:
return false
}
}
type duplJobScopeError struct {
*duplJobError
}
// NewDuplicateJobScopeError creates a new error object to represent a duplicate
// job scope error, for use by queue implementations.
func NewDuplicateJobScopeError(msg string) error {
return &duplJobScopeError{duplJobError: &duplJobError{msg: msg}}
}
// NewDuplicateJobScopeErrorf creates a new error object to represent a
// duplicate job scope error with a formatted message, for use by queue
// implementations.
func NewDuplicateJobScopeErrorf(msg string, args ...interface{}) error {
return NewDuplicateJobScopeError(fmt.Sprintf(msg, args...))
}
// MakeDuplicateJobScopeError constructs a duplicate job scope error from an
// existing error of any type, for use by queue implementations.
func MakeDuplicateJobScopeError(err error) error {
if err == nil {
return nil
}
return NewDuplicateJobScopeError(err.Error())
}
// IsDuplicateJobScopeError checks if an error is due to a duplicate job scope
// in the queue.
func IsDuplicateJobScopeError(err error) bool {
if err == nil {
return false
}
_, ok := errors.Cause(err).(*duplJobScopeError)
return ok
}