Skip to content

Instantly share code, notes, and snippets.

@cmdoptesc
Last active December 11, 2019 18:46
Show Gist options
  • Save cmdoptesc/7852bcb98386b32e41ec9815b55df12b to your computer and use it in GitHub Desktop.
Save cmdoptesc/7852bcb98386b32e41ec9815b55df12b to your computer and use it in GitHub Desktop.

Revisions

  1. cmdoptesc revised this gist Dec 11, 2019. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion listing_boto3_exceptions.md
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,8 @@ An ugly, but workable solution to find out what exceptions are available on each
    ```python
    import boto3
    client = boto3.client('sns') # or whatever client you're using
    client.exceptions.__dict__
    # client.exceptions.__dict__
    client.exceptions.__dict__['_code_to_exception'].keys()
    ```

    should print something like this:
  2. cmdoptesc created this gist Dec 11, 2019.
    167 changes: 167 additions & 0 deletions listing_boto3_exceptions.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,167 @@
    ## Listing Available AWS Boto3 Exceptions

    [alexpareto](https://github.com/alexpareto) commented on [Jul 22, 2019](https://github.com/boto/boto3/issues/1262#issuecomment-406882706)

    An ugly, but workable solution to find out what exceptions are available on each client from the command line:

    ```python
    import boto3
    client = boto3.client('sns') # or whatever client you're using
    client.exceptions.__dict__
    ```

    should print something like this:

    ```
    {'_code_to_exception': {'AuthorizationError': <class 'botocore.errorfactory.AuthorizationErrorException'>, 'EndpointDisabled': <class 'botocore.errorfactory.EndpointDisabledException'>, 'InternalError': <class 'botocore.errorfactory.InternalErrorException'>, 'InvalidParameter': <class 'botocore.errorfactory.InvalidParameterException'>, 'ParameterValueInvalid': <class 'botocore.errorfactory.InvalidParameterValueException'>, 'NotFound': <class 'botocore.errorfactory.NotFoundException'>, 'PlatformApplicationDisabled': <class 'botocore.errorfactory.PlatformApplicationDisabledException'>, 'SubscriptionLimitExceeded': <class 'botocore.errorfactory.SubscriptionLimitExceededException'>, 'Throttled': <class 'botocore.errorfactory.ThrottledException'>, 'TopicLimitExceeded': <class 'botocore.errorfactory.TopicLimitExceededException'>}}```
    ```

    ---

    [dacut](https://github.com/dacut) commented on [May 7, 2019](https://github.com/boto/boto3/issues/1262#issuecomment-489986337)

    There are currently (as of version 1.12.142) three base exceptions and two warnings:

    * BotoCoreError
    * ClientError
    * UndefinedModelAttributeError
    * ImminentRemovalWarning
    * UnsupportedTLSVersionWarning

    The `ClientError` exception appears to be raised when a remote call is made but the service returns an error. The `BotoCoreError` hierarchy appears to reflect issues in creating or handling the call itself. (Why `UndefinedModelAttributeError` is not a subclass of `BotoCoreError` is a mystery to me.)

    ## Structure of a ClientError
    Within `ClientError` (but _not_ `BotoCoreError`), there will be an `operation_name` attribute (should be a str) and a `response` attribute (should be a dict). The `response` attribute should have the following form (example from a malformed ec2.DescribeImages call):

    ```js
    {
    "Error": {
    "Code": "InvalidParameterValue",
    "Message": "The filter 'asdfasdf' is invalid"
    },
    "ResponseMetadata": {
    "RequestId": "aaaabbbb-cccc-dddd-eeee-ffff00001111",
    "HTTPStatusCode": 400,
    "HTTPHeaders": {
    "transfer-encoding": "chunked",
    "date": "Fri, 01 Jan 2100 00:00:00 GMT",
    "connection": "close",
    "server": "AmazonEC2"
    },
    "RetryAttempts": 0
    }
    }
    ```

    ## Error handling
    Typically, you want to handle specific error codes. Because this is largely only quasi-documented, this is what I typically do for error handling (in this case, handling the `InvalidParameterValue` from my ec2.DescribeImages call):

    ```python
    except ClientError as e:
    error_code = e.response.get("Error", {}).get("Code")
    if error_code == "InvalidParameterValue":
    # Do something
    pass
    else:
    raise
    ```

    Or, if I need to intermingle it with other exception handling code (much rarer) and am feeling lazy about it:

    ```python
    except Exception as e:
    error_code = getattr(e, "response", {}).get("Error", {}).get("Code")
    ...
    ```

    ## Exception hierarchy (May 7, 2019)
    Here's the full hierarchy of **statically defined** exceptions/warnings I found programmatically. Note that some exception classes use multiple inheritance.

    ```
    AliasConflictParameterError < ValidationError < BotoCoreError < Exception
    ApiVersionNotFoundError < BotoCoreError < Exception
    BaseEndpointResolverError < BotoCoreError < Exception
    BotoCoreError < Exception
    ChecksumError < BotoCoreError < Exception
    ClientError < Exception
    ConfigNotFound < BotoCoreError < Exception
    ConfigParseError < BotoCoreError < Exception
    ConnectTimeoutError < [ConnectionError < BotoCoreError < Exception, ConnectTimeout < [ConnectionError < RequestException < OSError < Exception, Timeout < RequestException < OSError < Exception]]
    ConnectionClosedError < HTTPClientError < BotoCoreError < Exception
    ConnectionError < BotoCoreError < Exception
    CredentialRetrievalError < BotoCoreError < Exception
    DataNotFoundError < BotoCoreError < Exception
    EndpointConnectionError < ConnectionError < BotoCoreError < Exception
    EventStreamError < ClientError < Exception
    HTTPClientError < BotoCoreError < Exception
    ImminentRemovalWarning < Warning < Exception
    IncompleteReadError < BotoCoreError < Exception
    InfiniteLoopConfigError < InvalidConfigError < BotoCoreError < Exception
    InvalidConfigError < BotoCoreError < Exception
    InvalidDNSNameError < BotoCoreError < Exception
    InvalidExpressionError < BotoCoreError < Exception
    InvalidMaxRetryAttemptsError < InvalidRetryConfigurationError < BotoCoreError < Exception
    InvalidRetryConfigurationError < BotoCoreError < Exception
    InvalidS3AddressingStyleError < BotoCoreError < Exception
    MD5UnavailableError < BotoCoreError < Exception
    MetadataRetrievalError < BotoCoreError < Exception
    MissingParametersError < BotoCoreError < Exception
    MissingServiceIdError < UndefinedModelAttributeError < Exception
    NoCredentialsError < BotoCoreError < Exception
    NoRegionError < BaseEndpointResolverError < BotoCoreError < Exception
    OperationNotPageableError < BotoCoreError < Exception
    PaginationError < BotoCoreError < Exception
    ParamValidationError < BotoCoreError < Exception
    PartialCredentialsError < BotoCoreError < Exception
    ProfileNotFound < BotoCoreError < Exception
    ProxyConnectionError < [ConnectionError < BotoCoreError < Exception, ProxyError < ConnectionError < RequestException < OSError < Exception]
    RangeError < ValidationError < BotoCoreError < Exception
    ReadTimeoutError < [HTTPClientError < BotoCoreError < Exception, ReadTimeout < Timeout < RequestException < OSError < Exception, ReadTimeoutError < [TimeoutError < HTTPError < Exception, RequestError < PoolError < HTTPError < Exception]]
    RefreshWithMFAUnsupportedError < BotoCoreError < Exception
    SSLError < [ConnectionError < BotoCoreError < Exception, SSLError < ConnectionError < RequestException < OSError < Exception]
    ServiceNotInRegionError < BotoCoreError < Exception
    StubAssertionError < [StubResponseError < BotoCoreError < Exception, AssertionError < Exception]
    StubResponseError < BotoCoreError < Exception
    UnStubbedResponseError < StubResponseError < BotoCoreError < Exception
    UndefinedModelAttributeError < Exception
    UnknownClientMethodError < BotoCoreError < Exception
    UnknownCredentialError < BotoCoreError < Exception
    UnknownEndpointError < [BaseEndpointResolverError < BotoCoreError < Exception, ValueError < Exception]
    UnknownKeyError < ValidationError < BotoCoreError < Exception
    UnknownParameterError < ValidationError < BotoCoreError < Exception
    UnknownServiceError < DataNotFoundError < BotoCoreError < Exception
    UnknownServiceStyle < BotoCoreError < Exception
    UnknownSignatureVersionError < BotoCoreError < Exception
    UnseekableStreamError < BotoCoreError < Exception
    UnsupportedSignatureVersionError < BotoCoreError < Exception
    UnsupportedTLSVersionWarning < Warning < Exception
    ValidationError < BotoCoreError < Exception
    WaiterConfigError < BotoCoreError < Exception
    WaiterError < BotoCoreError < Exception
    ```

    ## Appendix
    Code for how I generated the above (Python 3.7):

    ```python
    def hierarchy(t):
    if t is Exception or t is object:
    return t.__name__

    result = t.__name__ + " < "
    if len(t.__bases__) == 1:
    result += hierarchy(t.__bases__[0])
    else:
    result += "[" + ", ".join([hierarchy(base) for base in t.__bases__]) + "]"
    return result

    # Getting the list of base exceptions/warnings
    for key, value in sorted(botocore.exceptions.__dict__.items()):
    if isinstance(value, type) and (value.__bases__ == (Exception,) or value.__bases__ == (Warning,)):
    print(key)

    # Printing the hierarchy
    for key, value in sorted(botocore.exceptions.__dict__.items()):
    if isinstance(value, type):
    print(hierarchy(value))
    ```