Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/boto/exception.py @ 5:9b1c78e6ba9c draft default tip
"planemo upload commit 6c0a8142489327ece472c84e558c47da711a9142"
author | shellac |
---|---|
date | Mon, 01 Jun 2020 08:59:25 -0400 |
parents | 79f47841a781 |
children |
comparison
equal
deleted
inserted
replaced
4:79f47841a781 | 5:9b1c78e6ba9c |
---|---|
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ | |
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | |
3 # All rights reserved. | |
4 # | |
5 # Permission is hereby granted, free of charge, to any person obtaining a | |
6 # copy of this software and associated documentation files (the | |
7 # "Software"), to deal in the Software without restriction, including | |
8 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
9 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
10 # persons to whom the Software is furnished to do so, subject to the fol- | |
11 # lowing conditions: | |
12 # | |
13 # The above copyright notice and this permission notice shall be included | |
14 # in all copies or substantial portions of the Software. | |
15 # | |
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
22 # IN THE SOFTWARE. | |
23 | |
24 """ | |
25 Exception classes - Subclassing allows you to check for specific errors | |
26 """ | |
27 import base64 | |
28 import xml.sax | |
29 | |
30 import boto | |
31 | |
32 from boto import handler | |
33 from boto.compat import json, StandardError | |
34 from boto.resultset import ResultSet | |
35 | |
36 | |
37 class BotoClientError(StandardError): | |
38 """ | |
39 General Boto Client error (error accessing AWS) | |
40 """ | |
41 def __init__(self, reason, *args): | |
42 super(BotoClientError, self).__init__(reason, *args) | |
43 self.reason = reason | |
44 | |
45 def __repr__(self): | |
46 return 'BotoClientError: %s' % self.reason | |
47 | |
48 def __str__(self): | |
49 return 'BotoClientError: %s' % self.reason | |
50 | |
51 | |
52 class SDBPersistenceError(StandardError): | |
53 pass | |
54 | |
55 | |
56 class StoragePermissionsError(BotoClientError): | |
57 """ | |
58 Permissions error when accessing a bucket or key on a storage service. | |
59 """ | |
60 pass | |
61 | |
62 | |
63 class S3PermissionsError(StoragePermissionsError): | |
64 """ | |
65 Permissions error when accessing a bucket or key on S3. | |
66 """ | |
67 pass | |
68 | |
69 | |
70 class GSPermissionsError(StoragePermissionsError): | |
71 """ | |
72 Permissions error when accessing a bucket or key on GS. | |
73 """ | |
74 pass | |
75 | |
76 | |
77 class BotoServerError(StandardError): | |
78 def __init__(self, status, reason, body=None, *args): | |
79 super(BotoServerError, self).__init__(status, reason, body, *args) | |
80 self.status = status | |
81 self.reason = reason | |
82 self.body = body or '' | |
83 self.request_id = None | |
84 self.error_code = None | |
85 self._error_message = None | |
86 self.message = '' | |
87 self.box_usage = None | |
88 | |
89 if isinstance(self.body, bytes): | |
90 try: | |
91 self.body = self.body.decode('utf-8') | |
92 except UnicodeDecodeError: | |
93 boto.log.debug('Unable to decode body from bytes!') | |
94 | |
95 # Attempt to parse the error response. If body isn't present, | |
96 # then just ignore the error response. | |
97 if self.body: | |
98 # Check if it looks like a ``dict``. | |
99 if hasattr(self.body, 'items'): | |
100 # It's not a string, so trying to parse it will fail. | |
101 # But since it's data, we can work with that. | |
102 self.request_id = self.body.get('RequestId', None) | |
103 | |
104 if 'Error' in self.body: | |
105 # XML-style | |
106 error = self.body.get('Error', {}) | |
107 self.error_code = error.get('Code', None) | |
108 self.message = error.get('Message', None) | |
109 else: | |
110 # JSON-style. | |
111 self.message = self.body.get('message', None) | |
112 else: | |
113 try: | |
114 h = handler.XmlHandlerWrapper(self, self) | |
115 h.parseString(self.body) | |
116 except (TypeError, xml.sax.SAXParseException): | |
117 # What if it's JSON? Let's try that. | |
118 try: | |
119 parsed = json.loads(self.body) | |
120 | |
121 if 'RequestId' in parsed: | |
122 self.request_id = parsed['RequestId'] | |
123 if 'Error' in parsed: | |
124 if 'Code' in parsed['Error']: | |
125 self.error_code = parsed['Error']['Code'] | |
126 if 'Message' in parsed['Error']: | |
127 self.message = parsed['Error']['Message'] | |
128 | |
129 except (TypeError, ValueError): | |
130 # Remove unparsable message body so we don't include garbage | |
131 # in exception. But first, save self.body in self.error_message | |
132 # because occasionally we get error messages from Eucalyptus | |
133 # that are just text strings that we want to preserve. | |
134 self.message = self.body | |
135 self.body = None | |
136 | |
137 def __getattr__(self, name): | |
138 if name == 'error_message': | |
139 return self.message | |
140 if name == 'code': | |
141 return self.error_code | |
142 raise AttributeError | |
143 | |
144 def __setattr__(self, name, value): | |
145 if name == 'error_message': | |
146 self.message = value | |
147 else: | |
148 super(BotoServerError, self).__setattr__(name, value) | |
149 | |
150 def __repr__(self): | |
151 return '%s: %s %s\n%s' % (self.__class__.__name__, | |
152 self.status, self.reason, self.body) | |
153 | |
154 def __str__(self): | |
155 return '%s: %s %s\n%s' % (self.__class__.__name__, | |
156 self.status, self.reason, self.body) | |
157 | |
158 def startElement(self, name, attrs, connection): | |
159 pass | |
160 | |
161 def endElement(self, name, value, connection): | |
162 if name in ('RequestId', 'RequestID'): | |
163 self.request_id = value | |
164 elif name == 'Code': | |
165 self.error_code = value | |
166 elif name == 'Message': | |
167 self.message = value | |
168 elif name == 'BoxUsage': | |
169 self.box_usage = value | |
170 return None | |
171 | |
172 def _cleanupParsedProperties(self): | |
173 self.request_id = None | |
174 self.error_code = None | |
175 self.message = None | |
176 self.box_usage = None | |
177 | |
178 | |
179 class ConsoleOutput(object): | |
180 def __init__(self, parent=None): | |
181 self.parent = parent | |
182 self.instance_id = None | |
183 self.timestamp = None | |
184 self.comment = None | |
185 self.output = None | |
186 | |
187 def startElement(self, name, attrs, connection): | |
188 return None | |
189 | |
190 def endElement(self, name, value, connection): | |
191 if name == 'instanceId': | |
192 self.instance_id = value | |
193 elif name == 'output': | |
194 self.output = base64.b64decode(value) | |
195 else: | |
196 setattr(self, name, value) | |
197 | |
198 | |
199 class StorageCreateError(BotoServerError): | |
200 """ | |
201 Error creating a bucket or key on a storage service. | |
202 """ | |
203 def __init__(self, status, reason, body=None): | |
204 self.bucket = None | |
205 super(StorageCreateError, self).__init__(status, reason, body) | |
206 | |
207 def endElement(self, name, value, connection): | |
208 if name == 'BucketName': | |
209 self.bucket = value | |
210 else: | |
211 return super(StorageCreateError, self).endElement(name, value, connection) | |
212 | |
213 | |
214 class S3CreateError(StorageCreateError): | |
215 """ | |
216 Error creating a bucket or key on S3. | |
217 """ | |
218 pass | |
219 | |
220 | |
221 class GSCreateError(StorageCreateError): | |
222 """ | |
223 Error creating a bucket or key on GS. | |
224 """ | |
225 pass | |
226 | |
227 | |
228 class StorageCopyError(BotoServerError): | |
229 """ | |
230 Error copying a key on a storage service. | |
231 """ | |
232 pass | |
233 | |
234 | |
235 class S3CopyError(StorageCopyError): | |
236 """ | |
237 Error copying a key on S3. | |
238 """ | |
239 pass | |
240 | |
241 | |
242 class GSCopyError(StorageCopyError): | |
243 """ | |
244 Error copying a key on GS. | |
245 """ | |
246 pass | |
247 | |
248 | |
249 class SQSError(BotoServerError): | |
250 """ | |
251 General Error on Simple Queue Service. | |
252 """ | |
253 def __init__(self, status, reason, body=None): | |
254 self.detail = None | |
255 self.type = None | |
256 super(SQSError, self).__init__(status, reason, body) | |
257 | |
258 def startElement(self, name, attrs, connection): | |
259 return super(SQSError, self).startElement(name, attrs, connection) | |
260 | |
261 def endElement(self, name, value, connection): | |
262 if name == 'Detail': | |
263 self.detail = value | |
264 elif name == 'Type': | |
265 self.type = value | |
266 else: | |
267 return super(SQSError, self).endElement(name, value, connection) | |
268 | |
269 def _cleanupParsedProperties(self): | |
270 super(SQSError, self)._cleanupParsedProperties() | |
271 for p in ('detail', 'type'): | |
272 setattr(self, p, None) | |
273 | |
274 | |
275 class SQSDecodeError(BotoClientError): | |
276 """ | |
277 Error when decoding an SQS message. | |
278 """ | |
279 def __init__(self, reason, message): | |
280 super(SQSDecodeError, self).__init__(reason, message) | |
281 self.message = message | |
282 | |
283 def __repr__(self): | |
284 return 'SQSDecodeError: %s' % self.reason | |
285 | |
286 def __str__(self): | |
287 return 'SQSDecodeError: %s' % self.reason | |
288 | |
289 | |
290 class StorageResponseError(BotoServerError): | |
291 """ | |
292 Error in response from a storage service. | |
293 """ | |
294 def __init__(self, status, reason, body=None): | |
295 self.resource = None | |
296 super(StorageResponseError, self).__init__(status, reason, body) | |
297 | |
298 def startElement(self, name, attrs, connection): | |
299 return super(StorageResponseError, self).startElement( | |
300 name, attrs, connection) | |
301 | |
302 def endElement(self, name, value, connection): | |
303 if name == 'Resource': | |
304 self.resource = value | |
305 else: | |
306 return super(StorageResponseError, self).endElement( | |
307 name, value, connection) | |
308 | |
309 def _cleanupParsedProperties(self): | |
310 super(StorageResponseError, self)._cleanupParsedProperties() | |
311 for p in ('resource'): | |
312 setattr(self, p, None) | |
313 | |
314 | |
315 class S3ResponseError(StorageResponseError): | |
316 """ | |
317 Error in response from S3. | |
318 """ | |
319 pass | |
320 | |
321 | |
322 class GSResponseError(StorageResponseError): | |
323 """ | |
324 Error in response from GS. | |
325 """ | |
326 pass | |
327 | |
328 | |
329 class EC2ResponseError(BotoServerError): | |
330 """ | |
331 Error in response from EC2. | |
332 """ | |
333 def __init__(self, status, reason, body=None): | |
334 self.errors = None | |
335 self._errorResultSet = [] | |
336 super(EC2ResponseError, self).__init__(status, reason, body) | |
337 self.errors = [ | |
338 (e.error_code, e.error_message) for e in self._errorResultSet] | |
339 if len(self.errors): | |
340 self.error_code, self.error_message = self.errors[0] | |
341 | |
342 def startElement(self, name, attrs, connection): | |
343 if name == 'Errors': | |
344 self._errorResultSet = ResultSet([('Error', _EC2Error)]) | |
345 return self._errorResultSet | |
346 else: | |
347 return None | |
348 | |
349 def endElement(self, name, value, connection): | |
350 if name == 'RequestID': | |
351 self.request_id = value | |
352 else: | |
353 return None # don't call subclass here | |
354 | |
355 def _cleanupParsedProperties(self): | |
356 super(EC2ResponseError, self)._cleanupParsedProperties() | |
357 self._errorResultSet = [] | |
358 for p in ('errors'): | |
359 setattr(self, p, None) | |
360 | |
361 | |
362 class JSONResponseError(BotoServerError): | |
363 """ | |
364 This exception expects the fully parsed and decoded JSON response | |
365 body to be passed as the body parameter. | |
366 | |
367 :ivar status: The HTTP status code. | |
368 :ivar reason: The HTTP reason message. | |
369 :ivar body: The Python dict that represents the decoded JSON | |
370 response body. | |
371 :ivar error_message: The full description of the AWS error encountered. | |
372 :ivar error_code: A short string that identifies the AWS error | |
373 (e.g. ConditionalCheckFailedException) | |
374 """ | |
375 def __init__(self, status, reason, body=None, *args): | |
376 self.status = status | |
377 self.reason = reason | |
378 self.body = body | |
379 if self.body: | |
380 self.error_message = self.body.get('message', None) | |
381 self.error_code = self.body.get('__type', None) | |
382 if self.error_code: | |
383 self.error_code = self.error_code.split('#')[-1] | |
384 | |
385 | |
386 class DynamoDBResponseError(JSONResponseError): | |
387 pass | |
388 | |
389 | |
390 class SWFResponseError(JSONResponseError): | |
391 pass | |
392 | |
393 | |
394 class EmrResponseError(BotoServerError): | |
395 """ | |
396 Error in response from EMR | |
397 """ | |
398 pass | |
399 | |
400 | |
401 class _EC2Error(object): | |
402 def __init__(self, connection=None): | |
403 self.connection = connection | |
404 self.error_code = None | |
405 self.error_message = None | |
406 | |
407 def startElement(self, name, attrs, connection): | |
408 return None | |
409 | |
410 def endElement(self, name, value, connection): | |
411 if name == 'Code': | |
412 self.error_code = value | |
413 elif name == 'Message': | |
414 self.error_message = value | |
415 else: | |
416 return None | |
417 | |
418 | |
419 class SDBResponseError(BotoServerError): | |
420 """ | |
421 Error in responses from SDB. | |
422 """ | |
423 pass | |
424 | |
425 | |
426 class AWSConnectionError(BotoClientError): | |
427 """ | |
428 General error connecting to Amazon Web Services. | |
429 """ | |
430 pass | |
431 | |
432 | |
433 class StorageDataError(BotoClientError): | |
434 """ | |
435 Error receiving data from a storage service. | |
436 """ | |
437 pass | |
438 | |
439 | |
440 class S3DataError(StorageDataError): | |
441 """ | |
442 Error receiving data from S3. | |
443 """ | |
444 pass | |
445 | |
446 | |
447 class GSDataError(StorageDataError): | |
448 """ | |
449 Error receiving data from GS. | |
450 """ | |
451 pass | |
452 | |
453 | |
454 class InvalidUriError(Exception): | |
455 """Exception raised when URI is invalid.""" | |
456 | |
457 def __init__(self, message): | |
458 super(InvalidUriError, self).__init__(message) | |
459 self.message = message | |
460 | |
461 | |
462 class InvalidAclError(Exception): | |
463 """Exception raised when ACL XML is invalid.""" | |
464 | |
465 def __init__(self, message): | |
466 super(InvalidAclError, self).__init__(message) | |
467 self.message = message | |
468 | |
469 | |
470 class InvalidCorsError(Exception): | |
471 """Exception raised when CORS XML is invalid.""" | |
472 | |
473 def __init__(self, message): | |
474 super(InvalidCorsError, self).__init__(message) | |
475 self.message = message | |
476 | |
477 | |
478 class InvalidEncryptionConfigError(Exception): | |
479 """Exception raised when GCS encryption configuration XML is invalid.""" | |
480 | |
481 def __init__(self, message): | |
482 super(InvalidEncryptionConfigError, self).__init__(message) | |
483 self.message = message | |
484 | |
485 | |
486 class InvalidLifecycleConfigError(Exception): | |
487 """Exception raised when GCS lifecycle configuration XML is invalid.""" | |
488 | |
489 def __init__(self, message): | |
490 super(InvalidLifecycleConfigError, self).__init__(message) | |
491 self.message = message | |
492 | |
493 | |
494 class NoAuthHandlerFound(Exception): | |
495 """Is raised when no auth handlers were found ready to authenticate.""" | |
496 pass | |
497 | |
498 | |
499 # Enum class for resumable upload failure disposition. | |
500 class ResumableTransferDisposition(object): | |
501 # START_OVER means an attempt to resume an existing transfer failed, | |
502 # and a new resumable upload should be attempted (without delay). | |
503 START_OVER = 'START_OVER' | |
504 | |
505 # WAIT_BEFORE_RETRY means the resumable transfer failed but that it can | |
506 # be retried after a time delay within the current process. | |
507 WAIT_BEFORE_RETRY = 'WAIT_BEFORE_RETRY' | |
508 | |
509 # ABORT_CUR_PROCESS means the resumable transfer failed and that | |
510 # delaying/retrying within the current process will not help. If | |
511 # resumable transfer included a state tracker file the upload can be | |
512 # retried again later, in another process (e.g., a later run of gsutil). | |
513 ABORT_CUR_PROCESS = 'ABORT_CUR_PROCESS' | |
514 | |
515 # ABORT means the resumable transfer failed in a way that it does not | |
516 # make sense to continue in the current process, and further that the | |
517 # current tracker ID should not be preserved (in a tracker file if one | |
518 # was specified at resumable upload start time). If the user tries again | |
519 # later (e.g., a separate run of gsutil) it will get a new resumable | |
520 # upload ID. | |
521 ABORT = 'ABORT' | |
522 | |
523 | |
524 class ResumableUploadException(Exception): | |
525 """ | |
526 Exception raised for various resumable upload problems. | |
527 | |
528 self.disposition is of type ResumableTransferDisposition. | |
529 """ | |
530 | |
531 def __init__(self, message, disposition): | |
532 super(ResumableUploadException, self).__init__(message, disposition) | |
533 self.message = message | |
534 self.disposition = disposition | |
535 | |
536 def __repr__(self): | |
537 return 'ResumableUploadException("%s", %s)' % ( | |
538 self.message, self.disposition) | |
539 | |
540 | |
541 class ResumableDownloadException(Exception): | |
542 """ | |
543 Exception raised for various resumable download problems. | |
544 | |
545 self.disposition is of type ResumableTransferDisposition. | |
546 """ | |
547 | |
548 def __init__(self, message, disposition): | |
549 super(ResumableDownloadException, self).__init__(message, disposition) | |
550 self.message = message | |
551 self.disposition = disposition | |
552 | |
553 def __repr__(self): | |
554 return 'ResumableDownloadException("%s", %s)' % ( | |
555 self.message, self.disposition) | |
556 | |
557 | |
558 class TooManyRecordsException(Exception): | |
559 """ | |
560 Exception raised when a search of Route53 records returns more | |
561 records than requested. | |
562 """ | |
563 | |
564 def __init__(self, message): | |
565 super(TooManyRecordsException, self).__init__(message) | |
566 self.message = message | |
567 | |
568 | |
569 class PleaseRetryException(Exception): | |
570 """ | |
571 Indicates a request should be retried. | |
572 """ | |
573 def __init__(self, message, response=None): | |
574 self.message = message | |
575 self.response = response | |
576 | |
577 def __repr__(self): | |
578 return 'PleaseRetryException("%s", %s)' % ( | |
579 self.message, | |
580 self.response | |
581 ) | |
582 | |
583 | |
584 class InvalidInstanceMetadataError(Exception): | |
585 MSG = ( | |
586 "You can set the 'metadata_service_num_attempts' " | |
587 "in your boto config file to increase the number " | |
588 "of times boto will attempt to retrieve " | |
589 "credentials from the instance metadata service." | |
590 ) | |
591 def __init__(self, msg): | |
592 final_msg = msg + '\n' + self.MSG | |
593 super(InvalidInstanceMetadataError, self).__init__(final_msg) |