1
# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
2
# Copyright 2012-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License"). You
5
# may not use this file except in compliance with the License. A copy of
6
# the License is located at
7
#
8
# http://aws.amazon.com/apache2.0/
9
#
10
# or in the "license" file accompanying this file. This file is
11
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
# ANY KIND, either express or implied. See the License for the specific
13
# language governing permissions and limitations under the License.
14 11
from __future__ import unicode_literals
15 11
from botocore.vendored import requests
16 11
from botocore.vendored.requests.packages import urllib3
17

18

19 11
def _exception_from_packed_args(exception_cls, args=None, kwargs=None):
20
    # This is helpful for reducing Exceptions that only accept kwargs as
21
    # only positional arguments can be provided for __reduce__
22
    # Ideally, this would also be a class method on the BotoCoreError
23
    # but instance methods cannot be pickled.
24 11
    if args is None:
25 11
        args = ()
26 11
    if kwargs is None:
27 0
        kwargs = {}
28 11
    return exception_cls(*args, **kwargs)
29

30

31 11
class BotoCoreError(Exception):
32
    """
33
    The base exception class for BotoCore exceptions.
34

35
    :ivar msg: The descriptive message associated with the error.
36
    """
37 11
    fmt = 'An unspecified error occurred'
38

39 11
    def __init__(self, **kwargs):
40 11
        msg = self.fmt.format(**kwargs)
41 11
        Exception.__init__(self, msg)
42 11
        self.kwargs = kwargs
43

44 11
    def __reduce__(self):
45 11
        return _exception_from_packed_args, (self.__class__, None, self.kwargs)
46

47

48 11
class DataNotFoundError(BotoCoreError):
49
    """
50
    The data associated with a particular path could not be loaded.
51

52
    :ivar data_path: The data path that the user attempted to load.
53
    """
54 11
    fmt = 'Unable to load data for: {data_path}'
55

56

57 11
class UnknownServiceError(DataNotFoundError):
58
    """Raised when trying to load data for an unknown service.
59

60
    :ivar service_name: The name of the unknown service.
61

62
    """
63 11
    fmt = (
64
        "Unknown service: '{service_name}'. Valid service names are: "
65
        "{known_service_names}")
66

67

68 11
class ApiVersionNotFoundError(BotoCoreError):
69
    """
70
    The data associated with either the API version or a compatible one
71
    could not be loaded.
72

73
    :ivar data_path: The data path that the user attempted to load.
74
    :ivar api_version: The API version that the user attempted to load.
75
    """
76 11
    fmt = 'Unable to load data {data_path} for: {api_version}'
77

78

79 11
class HTTPClientError(BotoCoreError):
80 11
    fmt = 'An HTTP Client raised an unhandled exception: {error}'
81 11
    def __init__(self, request=None, response=None, **kwargs):
82 11
        self.request = request
83 11
        self.response = response
84 11
        super(HTTPClientError, self).__init__(**kwargs)
85

86 11
    def __reduce__(self):
87 11
        return _exception_from_packed_args, (
88
            self.__class__, (self.request, self.response), self.kwargs)
89

90

91 11
class ConnectionError(BotoCoreError):
92 11
    fmt = 'An HTTP Client failed to establish a connection: {error}'
93

94

95 11
class InvalidIMDSEndpointError(BotoCoreError):
96 11
    fmt = 'Invalid endpoint EC2 Instance Metadata endpoint: {endpoint}'
97

98

99 11
class EndpointConnectionError(ConnectionError):
100 11
    fmt = 'Could not connect to the endpoint URL: "{endpoint_url}"'
101

102

103 11
class SSLError(ConnectionError, requests.exceptions.SSLError):
104 11
    fmt = 'SSL validation failed for {endpoint_url} {error}'
105

106

107 11
class ConnectionClosedError(HTTPClientError):
108 11
    fmt = (
109
        'Connection was closed before we received a valid response '
110
        'from endpoint URL: "{endpoint_url}".')
111

112

113 11
class ReadTimeoutError(HTTPClientError, requests.exceptions.ReadTimeout,
114
                       urllib3.exceptions.ReadTimeoutError):
115 11
    fmt = 'Read timeout on endpoint URL: "{endpoint_url}"'
116

117

118 11
class ConnectTimeoutError(ConnectionError, requests.exceptions.ConnectTimeout):
119 11
    fmt = 'Connect timeout on endpoint URL: "{endpoint_url}"'
120

121

122 11
class ProxyConnectionError(ConnectionError, requests.exceptions.ProxyError):
123 11
    fmt = 'Failed to connect to proxy URL: "{proxy_url}"'
124

125

126 11
class NoCredentialsError(BotoCoreError):
127
    """
128
    No credentials could be found.
129
    """
130 11
    fmt = 'Unable to locate credentials'
131

132

133 11
class PartialCredentialsError(BotoCoreError):
134
    """
135
    Only partial credentials were found.
136

137
    :ivar cred_var: The missing credential variable name.
138

139
    """
140 11
    fmt = 'Partial credentials found in {provider}, missing: {cred_var}'
141

142

143 11
class CredentialRetrievalError(BotoCoreError):
144
    """
145
    Error attempting to retrieve credentials from a remote source.
146

147
    :ivar provider: The name of the credential provider.
148
    :ivar error_msg: The msg explaining why credentials could not be
149
        retrieved.
150

151
    """
152 11
    fmt = 'Error when retrieving credentials from {provider}: {error_msg}'
153

154

155 11
class UnknownSignatureVersionError(BotoCoreError):
156
    """
157
    Requested Signature Version is not known.
158

159
    :ivar signature_version: The name of the requested signature version.
160
    """
161 11
    fmt = 'Unknown Signature Version: {signature_version}.'
162

163

164 11
class ServiceNotInRegionError(BotoCoreError):
165
    """
166
    The service is not available in requested region.
167

168
    :ivar service_name: The name of the service.
169
    :ivar region_name: The name of the region.
170
    """
171 11
    fmt = 'Service {service_name} not available in region {region_name}'
172

173

174 11
class BaseEndpointResolverError(BotoCoreError):
175
    """Base error for endpoint resolving errors.
176

177
    Should never be raised directly, but clients can catch
178
    this exception if they want to generically handle any errors
179
    during the endpoint resolution process.
180

181
    """
182

183

184 11
class NoRegionError(BaseEndpointResolverError):
185
    """No region was specified."""
186 11
    fmt = 'You must specify a region.'
187

188

189 11
class UnknownEndpointError(BaseEndpointResolverError, ValueError):
190
    """
191
    Could not construct an endpoint.
192

193
    :ivar service_name: The name of the service.
194
    :ivar region_name: The name of the region.
195
    """
196 11
    fmt = (
197
        'Unable to construct an endpoint for '
198
        '{service_name} in region {region_name}')
199

200

201 11
class ProfileNotFound(BotoCoreError):
202
    """
203
    The specified configuration profile was not found in the
204
    configuration file.
205

206
    :ivar profile: The name of the profile the user attempted to load.
207
    """
208 11
    fmt = 'The config profile ({profile}) could not be found'
209

210

211 11
class ConfigParseError(BotoCoreError):
212
    """
213
    The configuration file could not be parsed.
214

215
    :ivar path: The path to the configuration file.
216
    """
217 11
    fmt = 'Unable to parse config file: {path}'
218

219

220 11
class ConfigNotFound(BotoCoreError):
221
    """
222
    The specified configuration file could not be found.
223

224
    :ivar path: The path to the configuration file.
225
    """
226 11
    fmt = 'The specified config file ({path}) could not be found.'
227

228

229 11
class MissingParametersError(BotoCoreError):
230
    """
231
    One or more required parameters were not supplied.
232

233
    :ivar object: The object that has missing parameters.
234
        This can be an operation or a parameter (in the
235
        case of inner params).  The str() of this object
236
        will be used so it doesn't need to implement anything
237
        other than str().
238
    :ivar missing: The names of the missing parameters.
239
    """
240 11
    fmt = ('The following required parameters are missing for '
241
           '{object_name}: {missing}')
242

243

244 11
class ValidationError(BotoCoreError):
245
    """
246
    An exception occurred validating parameters.
247

248
    Subclasses must accept a ``value`` and ``param``
249
    argument in their ``__init__``.
250

251
    :ivar value: The value that was being validated.
252
    :ivar param: The parameter that failed validation.
253
    :ivar type_name: The name of the underlying type.
254
    """
255 11
    fmt = ("Invalid value ('{value}') for param {param} "
256
           "of type {type_name} ")
257

258

259 11
class ParamValidationError(BotoCoreError):
260 11
    fmt = 'Parameter validation failed:\n{report}'
261

262

263
# These exceptions subclass from ValidationError so that code
264
# can just 'except ValidationError' to catch any possibly validation
265
# error.
266 11
class UnknownKeyError(ValidationError):
267
    """
268
    Unknown key in a struct parameter.
269

270
    :ivar value: The value that was being checked.
271
    :ivar param: The name of the parameter.
272
    :ivar choices: The valid choices the value can be.
273
    """
274 11
    fmt = ("Unknown key '{value}' for param '{param}'.  Must be one "
275
           "of: {choices}")
276

277

278 11
class RangeError(ValidationError):
279
    """
280
    A parameter value was out of the valid range.
281

282
    :ivar value: The value that was being checked.
283
    :ivar param: The parameter that failed validation.
284
    :ivar min_value: The specified minimum value.
285
    :ivar max_value: The specified maximum value.
286
    """
287 11
    fmt = ('Value out of range for param {param}: '
288
           '{min_value} <= {value} <= {max_value}')
289

290

291 11
class UnknownParameterError(ValidationError):
292
    """
293
    Unknown top level parameter.
294

295
    :ivar name: The name of the unknown parameter.
296
    :ivar operation: The name of the operation.
297
    :ivar choices: The valid choices the parameter name can be.
298
    """
299 11
    fmt = (
300
        "Unknown parameter '{name}' for operation {operation}.  Must be one "
301
        "of: {choices}"
302
    )
303

304

305 11
class InvalidRegionError(ValidationError, ValueError):
306
    """
307
    Invalid region_name provided to client or resource.
308

309
    :ivar region_name: region_name that was being validated.
310
    """
311 11
    fmt = (
312
        "Provided region_name '{region_name}' doesn't match a supported format."
313
    )
314

315

316 11
class AliasConflictParameterError(ValidationError):
317
    """
318
    Error when an alias is provided for a parameter as well as the original.
319

320
    :ivar original: The name of the original parameter.
321
    :ivar alias: The name of the alias
322
    :ivar operation: The name of the operation.
323
    """
324 11
    fmt = (
325
        "Parameter '{original}' and its alias '{alias}' were provided "
326
        "for operation {operation}.  Only one of them may be used."
327
    )
328

329

330 11
class UnknownServiceStyle(BotoCoreError):
331
    """
332
    Unknown style of service invocation.
333

334
    :ivar service_style: The style requested.
335
    """
336 11
    fmt = 'The service style ({service_style}) is not understood.'
337

338

339 11
class PaginationError(BotoCoreError):
340 11
    fmt = 'Error during pagination: {message}'
341

342

343 11
class OperationNotPageableError(BotoCoreError):
344 11
    fmt = 'Operation cannot be paginated: {operation_name}'
345

346

347 11
class ChecksumError(BotoCoreError):
348
    """The expected checksum did not match the calculated checksum.
349

350
    """
351 11
    fmt = ('Checksum {checksum_type} failed, expected checksum '
352
           '{expected_checksum} did not match calculated checksum '
353
           '{actual_checksum}.')
354

355

356 11
class UnseekableStreamError(BotoCoreError):
357
    """Need to seek a stream, but stream does not support seeking.
358

359
    """
360 11
    fmt = ('Need to rewind the stream {stream_object}, but stream '
361
           'is not seekable.')
362

363

364 11
class WaiterError(BotoCoreError):
365
    """Waiter failed to reach desired state."""
366 11
    fmt = 'Waiter {name} failed: {reason}'
367

368 11
    def __init__(self, name, reason, last_response):
369 11
        super(WaiterError, self).__init__(name=name, reason=reason)
370 11
        self.last_response = last_response
371

372

373 11
class IncompleteReadError(BotoCoreError):
374
    """HTTP response did not return expected number of bytes."""
375 11
    fmt = ('{actual_bytes} read, but total bytes '
376
           'expected is {expected_bytes}.')
377

378

379 11
class InvalidExpressionError(BotoCoreError):
380
    """Expression is either invalid or too complex."""
381 11
    fmt = 'Invalid expression {expression}: Only dotted lookups are supported.'
382

383

384 11
class UnknownCredentialError(BotoCoreError):
385
    """Tried to insert before/after an unregistered credential type."""
386 11
    fmt = 'Credential named {name} not found.'
387

388

389 11
class WaiterConfigError(BotoCoreError):
390
    """Error when processing waiter configuration."""
391 11
    fmt = 'Error processing waiter config: {error_msg}'
392

393

394 11
class UnknownClientMethodError(BotoCoreError):
395
    """Error when trying to access a method on a client that does not exist."""
396 11
    fmt = 'Client does not have method: {method_name}'
397

398

399 11
class UnsupportedSignatureVersionError(BotoCoreError):
400
    """Error when trying to use an unsupported Signature Version."""
401 11
    fmt = 'Signature version is not supported: {signature_version}'
402

403

404 11
class ClientError(Exception):
405 11
    MSG_TEMPLATE = (
406
        'An error occurred ({error_code}) when calling the {operation_name} '
407
        'operation{retry_info}: {error_message}')
408

409 11
    def __init__(self, error_response, operation_name):
410 11
        retry_info = self._get_retry_info(error_response)
411 11
        error = error_response.get('Error', {})
412 11
        msg = self.MSG_TEMPLATE.format(
413
            error_code=error.get('Code', 'Unknown'),
414
            error_message=error.get('Message', 'Unknown'),
415
            operation_name=operation_name,
416
            retry_info=retry_info,
417
        )
418 11
        super(ClientError, self).__init__(msg)
419 11
        self.response = error_response
420 11
        self.operation_name = operation_name
421

422 11
    def _get_retry_info(self, response):
423 11
        retry_info = ''
424 11
        if 'ResponseMetadata' in response:
425 11
            metadata = response['ResponseMetadata']
426 11
            if metadata.get('MaxAttemptsReached', False):
427 11
                if 'RetryAttempts' in metadata:
428 11
                    retry_info = (' (reached max retries: %s)' %
429
                                  metadata['RetryAttempts'])
430 11
        return retry_info
431

432 11
    def __reduce__(self):
433
        # Subclasses of ClientError's are dynamically generated and
434
        # cannot be pickled unless they are attributes of a
435
        # module. So at the very least return a ClientError back.
436 11
        return ClientError, (self.response, self.operation_name)
437

438

439 11
class EventStreamError(ClientError):
440 11
    pass
441

442

443 11
class UnsupportedTLSVersionWarning(Warning):
444
    """Warn when an openssl version that uses TLS 1.2 is required"""
445 11
    pass
446

447

448 11
class ImminentRemovalWarning(Warning):
449 11
    pass
450

451

452 11
class InvalidDNSNameError(BotoCoreError):
453
    """Error when virtual host path is forced on a non-DNS compatible bucket"""
454 11
    fmt = (
455
        'Bucket named {bucket_name} is not DNS compatible. Virtual '
456
        'hosted-style addressing cannot be used. The addressing style '
457
        'can be configured by removing the addressing_style value '
458
        'or setting that value to \'path\' or \'auto\' in the AWS Config '
459
        'file or in the botocore.client.Config object.'
460
    )
461

462

463 11
class InvalidS3AddressingStyleError(BotoCoreError):
464
    """Error when an invalid path style is specified"""
465 11
    fmt = (
466
        'S3 addressing style {s3_addressing_style} is invalid. Valid options '
467
        'are: \'auto\', \'virtual\', and \'path\''
468
    )
469

470

471 11
class UnsupportedS3ArnError(BotoCoreError):
472
    """Error when S3 ARN provided to Bucket parameter is not supported"""
473 11
    fmt = (
474
        'S3 ARN {arn} provided to "Bucket" parameter is invalid. Only '
475
        'ARNs for S3 access-points are supported.'
476
    )
477

478

479 11
class UnsupportedS3ControlArnError(BotoCoreError):
480
    """Error when S3 ARN provided to S3 control parameter is not supported"""
481 11
    fmt = (
482
        'S3 ARN "{arn}" provided is invalid for this operation. {msg}'
483
    )
484

485

486 11
class InvalidHostLabelError(BotoCoreError):
487
    """Error when an invalid host label would be bound to an endpoint"""
488 11
    fmt = (
489
        'Invalid host label to be bound to the hostname of the endpoint: '
490
        '"{label}".'
491
    )
492

493

494 11
class UnsupportedOutpostResourceError(BotoCoreError):
495
    """Error when S3 Outpost ARN provided to Bucket parameter is incomplete"""
496 11
    fmt = (
497
        'S3 Outpost ARN resource "{resource_name}" provided to "Bucket" '
498
        'parameter is invalid. Only ARNs for S3 Outpost arns with an '
499
        'access-point sub-resource are supported.'
500
    )
501

502

503 11
class UnsupportedS3AccesspointConfigurationError(BotoCoreError):
504
    """Error when an unsupported configuration is used with access-points"""
505 11
    fmt = (
506
        'Unsupported configuration when using S3 access-points: {msg}'
507
    )
508

509 11
class InvalidEndpointDiscoveryConfigurationError(BotoCoreError):
510
    """Error when invalid value supplied for endpoint_discovery_enabled"""
511 11
    fmt = (
512
        'Unsupported configuration value for endpoint_discovery_enabled. '
513
        'Expected one of ("true", "false", "auto") but got {config_value}.'
514
    )
515

516 11
class UnsupportedS3ControlConfigurationError(BotoCoreError):
517
    """Error when an unsupported configuration is used with S3 Control"""
518 11
    fmt = (
519
        'Unsupported configuration when using S3 Control: {msg}'
520
    )
521

522

523 11
class InvalidRetryConfigurationError(BotoCoreError):
524
    """Error when invalid retry configuration is specified"""
525 11
    fmt = (
526
        'Cannot provide retry configuration for "{retry_config_option}". '
527
        'Valid retry configuration options are: \'max_attempts\''
528
    )
529

530

531 11
class InvalidMaxRetryAttemptsError(InvalidRetryConfigurationError):
532
    """Error when invalid retry configuration is specified"""
533 11
    fmt = (
534
        'Value provided to "max_attempts": {provided_max_attempts} must '
535
        'be an integer greater than or equal to {min_value}.'
536
    )
537

538

539 11
class InvalidRetryModeError(InvalidRetryConfigurationError):
540
    """Error when invalid retry mode configuration is specified"""
541 11
    fmt = (
542
        'Invalid value provided to "mode": "{provided_retry_mode}" must '
543
        'be one of: "legacy", "standard", "adaptive"'
544
    )
545

546

547 11
class InvalidS3UsEast1RegionalEndpointConfigError(BotoCoreError):
548
    """Error for invalid s3 us-east-1 regional endpoints configuration"""
549 11
    fmt = (
550
        'S3 us-east-1 regional endpoint option '
551
        '{s3_us_east_1_regional_endpoint_config} is '
552
        'invalid. Valid options are: "legacy", "regional"'
553
    )
554

555

556 11
class InvalidSTSRegionalEndpointsConfigError(BotoCoreError):
557
    """Error when invalid sts regional endpoints configuration is specified"""
558 11
    fmt = (
559
        'STS regional endpoints option {sts_regional_endpoints_config} is '
560
        'invalid. Valid options are: "legacy", "regional"'
561
    )
562

563

564 11
class StubResponseError(BotoCoreError):
565 11
    fmt = 'Error getting response stub for operation {operation_name}: {reason}'
566

567

568 11
class StubAssertionError(StubResponseError, AssertionError):
569 11
    pass
570

571

572 11
class UnStubbedResponseError(StubResponseError):
573 11
    pass
574

575

576 11
class InvalidConfigError(BotoCoreError):
577 11
    fmt = '{error_msg}'
578

579

580 11
class InfiniteLoopConfigError(InvalidConfigError):
581 11
    fmt = (
582
        'Infinite loop in credential configuration detected. Attempting to '
583
        'load from profile {source_profile} which has already been visited. '
584
        'Visited profiles: {visited_profiles}'
585
    )
586

587

588 11
class RefreshWithMFAUnsupportedError(BotoCoreError):
589 11
    fmt = 'Cannot refresh credentials: MFA token required.'
590

591

592 11
class MD5UnavailableError(BotoCoreError):
593 11
    fmt = "This system does not support MD5 generation."
594

595

596 11
class MetadataRetrievalError(BotoCoreError):
597 11
    fmt = "Error retrieving metadata: {error_msg}"
598

599

600 11
class UndefinedModelAttributeError(Exception):
601 11
    pass
602

603

604 11
class MissingServiceIdError(UndefinedModelAttributeError):
605 11
    fmt = (
606
        "The model being used for the service {service_name} is missing the "
607
        "serviceId metadata property, which is required."
608
    )
609

610 11
    def __init__(self, **kwargs):
611 11
        msg = self.fmt.format(**kwargs)
612 11
        Exception.__init__(self, msg)
613 11
        self.kwargs = kwargs
614

615

616 11
class SSOError(BotoCoreError):
617 11
    fmt = "An unspecified error happened when resolving SSO credentials"
618

619

620 11
class SSOTokenLoadError(SSOError):
621 11
    fmt = "Error loading SSO Token: {error_msg}"
622

623

624 11
class UnauthorizedSSOTokenError(SSOError):
625 11
    fmt = (
626
        "The SSO session associated with this profile has expired or is "
627
        "otherwise invalid. To refresh this SSO session run aws sso login "
628
        "with the corresponding profile."
629
    )
630

631

632 11
class CapacityNotAvailableError(BotoCoreError):
633 11
    fmt = (
634
        'Insufficient request capacity available.'
635
    )

Read our documentation on viewing source code .

Loading