Skip to content

Instantly share code, notes, and snippets.

@cmdoptesc
Last active December 11, 2019 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmdoptesc/7852bcb98386b32e41ec9815b55df12b to your computer and use it in GitHub Desktop.
Save cmdoptesc/7852bcb98386b32e41ec9815b55df12b to your computer and use it in GitHub Desktop.
Listing Boto3 Exceptions

Listing Available AWS Boto3 Exceptions

alexpareto commented on Jul 22, 2019

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

import boto3
client = boto3.client('sns')  # or whatever client you're using
# client.exceptions.__dict__
client.exceptions.__dict__['_code_to_exception'].keys()

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 commented on May 7, 2019

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):

{
    "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):

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:

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):

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))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment