1
2
3
4
5
6
7
8
9
10
11 package errors
12
13 import (
14 "fmt"
15 "time"
16
17 "github.com/letsencrypt/boulder/identifier"
18 "google.golang.org/grpc/codes"
19 "google.golang.org/grpc/status"
20 )
21
22
23
24
25
26 type ErrorType int
27
28
29 const (
30
31
32 InternalServer ErrorType = iota
33 _
34 Malformed
35 Unauthorized
36 NotFound
37 RateLimit
38 RejectedIdentifier
39 InvalidEmail
40 ConnectionFailure
41 _
42 CAA
43 MissingSCTs
44 Duplicate
45 OrderNotReady
46 DNS
47 BadPublicKey
48 BadCSR
49 AlreadyRevoked
50 BadRevocationReason
51 UnsupportedContact
52
53 UnknownSerial
54 )
55
56 func (ErrorType) Error() string {
57 return "urn:ietf:params:acme:error"
58 }
59
60
61 type BoulderError struct {
62 Type ErrorType
63 Detail string
64 SubErrors []SubBoulderError
65
66
67
68 RetryAfter time.Duration
69 }
70
71
72
73 type SubBoulderError struct {
74 *BoulderError
75 Identifier identifier.ACMEIdentifier
76 }
77
78 func (be *BoulderError) Error() string {
79 return be.Detail
80 }
81
82 func (be *BoulderError) Unwrap() error {
83 return be.Type
84 }
85
86
87
88
89
90
91 func (be *BoulderError) GRPCStatus() *status.Status {
92 var c codes.Code
93 switch be.Type {
94 case InternalServer:
95 c = codes.Internal
96 case Malformed:
97 c = codes.InvalidArgument
98 case Unauthorized:
99 c = codes.PermissionDenied
100 case NotFound:
101 c = codes.NotFound
102 case RateLimit:
103 c = codes.Unknown
104 case RejectedIdentifier:
105 c = codes.InvalidArgument
106 case InvalidEmail:
107 c = codes.InvalidArgument
108 case ConnectionFailure:
109 c = codes.Unavailable
110 case CAA:
111 c = codes.FailedPrecondition
112 case MissingSCTs:
113 c = codes.Internal
114 case Duplicate:
115 c = codes.AlreadyExists
116 case OrderNotReady:
117 c = codes.FailedPrecondition
118 case DNS:
119 c = codes.Unknown
120 case BadPublicKey:
121 c = codes.InvalidArgument
122 case BadCSR:
123 c = codes.InvalidArgument
124 case AlreadyRevoked:
125 c = codes.AlreadyExists
126 case BadRevocationReason:
127 c = codes.InvalidArgument
128 case UnsupportedContact:
129 c = codes.InvalidArgument
130 default:
131 c = codes.Unknown
132 }
133 return status.New(c, be.Error())
134 }
135
136
137
138 func (be *BoulderError) WithSubErrors(subErrs []SubBoulderError) *BoulderError {
139 return &BoulderError{
140 Type: be.Type,
141 Detail: be.Detail,
142 SubErrors: append(be.SubErrors, subErrs...),
143 RetryAfter: be.RetryAfter,
144 }
145 }
146
147
148 func New(errType ErrorType, msg string, args ...interface{}) error {
149 return &BoulderError{
150 Type: errType,
151 Detail: fmt.Sprintf(msg, args...),
152 }
153 }
154
155 func InternalServerError(msg string, args ...interface{}) error {
156 return New(InternalServer, msg, args...)
157 }
158
159 func MalformedError(msg string, args ...interface{}) error {
160 return New(Malformed, msg, args...)
161 }
162
163 func UnauthorizedError(msg string, args ...interface{}) error {
164 return New(Unauthorized, msg, args...)
165 }
166
167 func NotFoundError(msg string, args ...interface{}) error {
168 return New(NotFound, msg, args...)
169 }
170
171 func RateLimitError(retryAfter time.Duration, msg string, args ...interface{}) error {
172 return &BoulderError{
173 Type: RateLimit,
174 Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/", args...),
175 RetryAfter: retryAfter,
176 }
177 }
178
179 func DuplicateCertificateError(retryAfter time.Duration, msg string, args ...interface{}) error {
180 return &BoulderError{
181 Type: RateLimit,
182 Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/duplicate-certificate-limit/", args...),
183 RetryAfter: retryAfter,
184 }
185 }
186
187 func FailedValidationError(retryAfter time.Duration, msg string, args ...interface{}) error {
188 return &BoulderError{
189 Type: RateLimit,
190 Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/failed-validation-limit/", args...),
191 RetryAfter: retryAfter,
192 }
193 }
194
195 func RegistrationsPerIPError(retryAfter time.Duration, msg string, args ...interface{}) error {
196 return &BoulderError{
197 Type: RateLimit,
198 Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/too-many-registrations-for-this-ip/", args...),
199 RetryAfter: retryAfter,
200 }
201 }
202
203 func RejectedIdentifierError(msg string, args ...interface{}) error {
204 return New(RejectedIdentifier, msg, args...)
205 }
206
207 func InvalidEmailError(msg string, args ...interface{}) error {
208 return New(InvalidEmail, msg, args...)
209 }
210
211 func UnsupportedContactError(msg string, args ...interface{}) error {
212 return New(UnsupportedContact, msg, args...)
213 }
214
215 func ConnectionFailureError(msg string, args ...interface{}) error {
216 return New(ConnectionFailure, msg, args...)
217 }
218
219 func CAAError(msg string, args ...interface{}) error {
220 return New(CAA, msg, args...)
221 }
222
223 func MissingSCTsError(msg string, args ...interface{}) error {
224 return New(MissingSCTs, msg, args...)
225 }
226
227 func DuplicateError(msg string, args ...interface{}) error {
228 return New(Duplicate, msg, args...)
229 }
230
231 func OrderNotReadyError(msg string, args ...interface{}) error {
232 return New(OrderNotReady, msg, args...)
233 }
234
235 func DNSError(msg string, args ...interface{}) error {
236 return New(DNS, msg, args...)
237 }
238
239 func BadPublicKeyError(msg string, args ...interface{}) error {
240 return New(BadPublicKey, msg, args...)
241 }
242
243 func BadCSRError(msg string, args ...interface{}) error {
244 return New(BadCSR, msg, args...)
245 }
246
247 func AlreadyRevokedError(msg string, args ...interface{}) error {
248 return New(AlreadyRevoked, msg, args...)
249 }
250
251 func BadRevocationReasonError(reason int64) error {
252 return New(BadRevocationReason, "disallowed revocation reason: %d", reason)
253 }
254
255 func UnknownSerialError() error {
256 return New(UnknownSerial, "unknown serial")
257 }
258
View as plain text