11from defusedxml import ElementTree
22import six
33
4+
45class ResponseError (Exception ):
56
67 """An error received from the Recurly API in response to an HTTP
@@ -13,39 +14,37 @@ def __init__(self, response_xml):
1314 def response_doc (self ):
1415 """The XML document received from the service."""
1516 try :
16- return self .__dict__ [' response_doc' ]
17+ return self .__dict__ [" response_doc" ]
1718 except KeyError :
18- self .__dict__ ['response_doc' ] = ElementTree .fromstring (
19- self .response_xml
20- )
21- return self .__dict__ ['response_doc' ]
19+ self .__dict__ ["response_doc" ] = ElementTree .fromstring (self .response_xml )
20+ return self .__dict__ ["response_doc" ]
2221
2322 @property
2423 def symbol (self ):
2524 """The machine-readable identifier for the error."""
26- el = self .response_doc .find (' symbol' )
25+ el = self .response_doc .find (" symbol" )
2726 if el is not None :
2827 return el .text
2928
3029 @property
3130 def message (self ):
3231 """The human-readable description of the error."""
33- el = self .response_doc .find (' description' )
32+ el = self .response_doc .find (" description" )
3433 if el is not None :
3534 return el .text
3635
3736 @property
3837 def details (self ):
3938 """A further human-readable elaboration on the error."""
40- el = self .response_doc .find (' details' )
39+ el = self .response_doc .find (" details" )
4140 if el is not None :
4241 return el .text
4342
4443 @property
4544 def error (self ):
4645 """A fall-back error message in the event no more specific
4746 error is given."""
48- el = self .response_doc .find (' error' )
47+ el = self .response_doc .find (" error" )
4948 if el is not None :
5049 return el .text
5150
@@ -58,13 +57,14 @@ def __unicode__(self):
5857 return self .error
5958 details = self .details
6059 if details is not None :
61- return six .u (' %s: %s %s' ) % (symbol , self .message , details )
62- return six .u (' %s: %s' ) % (symbol , self .message )
60+ return six .u (" %s: %s %s" ) % (symbol , self .message , details )
61+ return six .u (" %s: %s" ) % (symbol , self .message )
6362
6463
6564class ClientError (ResponseError ):
6665 """An error resulting from a problem in the client's request (that
6766 is, an error with an HTTP ``4xx`` status code)."""
67+
6868 pass
6969
7070
@@ -76,11 +76,13 @@ class BadRequestError(ClientError):
7676 Resubmitting the request will likely result in the same error.
7777
7878 """
79+
7980 pass
8081
8182
8283class ConfigurationError (Exception ):
8384 """An error related to a bad configuration"""
85+
8486 pass
8587
8688
@@ -99,6 +101,7 @@ def __unicode__(self):
99101class PaymentRequiredError (ClientError ):
100102 """An error indicating your Recurly account is in production mode
101103 but is not in good standing (HTTP ``402 Payment Required``)."""
104+
102105 pass
103106
104107
@@ -110,18 +113,21 @@ class ForbiddenError(ClientError):
110113 your login credentials are for the appropriate account.
111114
112115 """
116+
113117 pass
114118
115119
116120class NotFoundError (ClientError ):
117121 """An error for when the resource was not found with the given
118122 identifier (HTTP ``404 Not Found``)."""
123+
119124 pass
120125
121126
122127class NotAcceptableError (ClientError ):
123128 """An error for when the client's request could not be accepted by
124129 the remote service (HTTP ``406 Not Acceptable``)."""
130+
125131 pass
126132
127133
@@ -134,12 +140,14 @@ class PreconditionFailedError(ClientError):
134140 corresponds to the HTTP ``412 Precondition Failed`` status code.
135141
136142 """
143+
137144 pass
138145
139146
140147class UnsupportedMediaTypeError (ClientError ):
141148 """An error resulting from the submission as an unsupported media
142149 type (HTTP ``415 Unsupported Media Type``)."""
150+
143151 pass
144152
145153
@@ -153,42 +161,42 @@ def __init__(self, response_doc):
153161 @property
154162 def error_code (self ):
155163 """The machine-readable identifier for the error."""
156- el = self .response_doc .find (' error_code' )
164+ el = self .response_doc .find (" error_code" )
157165 if el is not None :
158166 return el .text
159167
160168 @property
161169 def error_category (self ):
162170 """The machine-readable identifier for the error category."""
163- el = self .response_doc .find (' error_category' )
171+ el = self .response_doc .find (" error_category" )
164172 if el is not None :
165173 return el .text
166174
167175 @property
168176 def customer_message (self ):
169177 """Recommended message for the customer"""
170- el = self .response_doc .find (' customer_message' )
178+ el = self .response_doc .find (" customer_message" )
171179 if el is not None :
172180 return el .text
173181
174182 @property
175183 def merchant_message (self ):
176184 """Recommended message for the merchant"""
177- el = self .response_doc .find (' merchant_message' )
185+ el = self .response_doc .find (" merchant_message" )
178186 if el is not None :
179187 return el .text
180188
181189 @property
182190 def gateway_error_code (self ):
183191 """Error code from the gateway"""
184- el = self .response_doc .find (' gateway_error_code' )
192+ el = self .response_doc .find (" gateway_error_code" )
185193 if el is not None :
186194 return el .text
187195
188196 @property
189197 def three_d_secure_action_token_id (self ):
190198 """3DS Action Token ID for further authentication"""
191- el = self .response_doc .find (' three_d_secure_action_token_id' )
199+ el = self .response_doc .find (" three_d_secure_action_token_id" )
192200 if el is not None :
193201 return el .text
194202
@@ -201,16 +209,16 @@ class ValidationError(ClientError):
201209 @property
202210 def transaction_error (self ):
203211 """The transaction error object."""
204- error = self .response_doc .find (' transaction_error' )
212+ error = self .response_doc .find (" transaction_error" )
205213 if error is not None :
206214 return TransactionError (error )
207215
208216 @property
209217 def transaction_error_code (self ):
210218 """The machine-readable error code for a transaction error."""
211- error = self .response_doc .find (' transaction_error' )
219+ error = self .response_doc .find (" transaction_error" )
212220 if error is not None :
213- code = error .find (' error_code' )
221+ code = error .find (" error_code" )
214222 if code is not None :
215223 return code .text
216224
@@ -228,7 +236,7 @@ def __str__(self):
228236 return self .__unicode__ ()
229237
230238 def __unicode__ (self ):
231- return six .u (' %s: %s %s' ) % (self .symbol , self .field , self .message )
239+ return six .u (" %s: %s %s" ) % (self .symbol , self .field , self .message )
232240
233241 @property
234242 def errors (self ):
@@ -240,14 +248,14 @@ def errors(self):
240248
241249 """
242250 try :
243- return self .__dict__ [' errors' ]
251+ return self .__dict__ [" errors" ]
244252 except KeyError :
245253 pass
246254
247255 suberrors = dict ()
248- for err in self .response_doc .findall (' error' ):
249- field = err .attrib [' field' ]
250- symbol = err .attrib [' symbol' ]
256+ for err in self .response_doc .findall (" error" ):
257+ field = err .attrib [" field" ]
258+ symbol = err .attrib [" symbol" ]
251259 message = err .text
252260 sub_err = self .Suberror (field , symbol , message )
253261
@@ -260,28 +268,33 @@ def errors(self):
260268 else :
261269 suberrors [field ] = sub_err
262270
263- self .__dict__ [' errors' ] = suberrors
271+ self .__dict__ [" errors" ] = suberrors
264272 return suberrors
265273
266274 def __unicode__ (self ):
267275 all_error_strings = []
268276 for error_key in sorted (self .errors .keys ()):
269277 error = self .errors [error_key ]
270278 if isinstance (error , (tuple , list )):
271- all_error_strings += [six .text_type (e ) for e in error ] # multiple errors on field
279+ all_error_strings += [
280+ six .text_type (e ) for e in error
281+ ] # multiple errors on field
272282 else :
273283 all_error_strings .append (six .text_type (error ))
274- return six .u ('; ' ).join (all_error_strings )
284+ return six .u ("; " ).join (all_error_strings )
285+
275286
276287class ServerError (ResponseError ):
277288 """An error resulting from a problem creating the server's response
278289 to the request (that is, an error with an HTTP ``5xx`` status code)."""
290+
279291 pass
280292
281293
282294class InternalServerError (ServerError ):
283295 """An unexpected general server error (HTTP ``500 Internal Server
284296 Error``)."""
297+
285298 pass
286299
287300
@@ -293,6 +306,7 @@ class BadGatewayError(ServerError):
293306 Try the request again.
294307
295308 """
309+
296310 pass
297311
298312
@@ -303,6 +317,7 @@ class ServiceUnavailableError(ServerError):
303317 response. Try the request again.
304318
305319 """
320+
306321 pass
307322
308323
@@ -313,6 +328,7 @@ class GatewayTimeoutError(ServerError):
313328 response. Try the request again.
314329
315330 """
331+
316332 pass
317333
318334
@@ -335,14 +351,17 @@ class UnexpectedClientError(UnexpectedStatusError):
335351 not be used for classes mapped in the `error_classes` dict.
336352
337353 """
354+
338355 pass
339356
357+
340358class UnexpectedServerError (UnexpectedStatusError ):
341359 """An error resulting from an unexpected status code in
342360 the range 500-599 of HTTP status codes. This class should
343361 not be used for classes mapped in the `error_classes` dict.
344362
345363 """
364+
346365 pass
347366
348367
@@ -369,13 +388,16 @@ def error_class_for_http_status(status):
369388 try :
370389 return error_classes [status ]
371390 except KeyError :
391+
372392 def new_status_error (xml_response ):
373- if ( status > 400 and status < 500 ) :
393+ if status > 400 and status < 500 :
374394 return UnexpectedClientError (status , xml_response )
375- if ( status > 500 and status < 600 ) :
395+ if status > 500 and status < 600 :
376396 return UnexpectedServerError (status , xml_response )
377397 return UnexpectedStatusError (status , xml_response )
398+
378399 return new_status_error
379400
401+
380402other_errors = [ConfigurationError ]
381403__all__ = [x .__name__ for x in list (error_classes .values ()) + other_errors ]
0 commit comments