Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/boto/exception.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
| author | shellac |
|---|---|
| date | Mon, 22 Mar 2021 18:12:50 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4f3585e2f14b |
|---|---|
| 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) |
