Comment gérer les erreurs avec boto3?

209

J'essaie de comprendre comment gérer correctement les erreurs avec boto3.

J'essaie de créer un utilisateur IAM:

def create_user(username, iam_conn):
    try:
        user = iam_conn.create_user(UserName=username)
        return user
    except Exception as e:
        return e

Lorsque l'appel à create_user réussit, j'obtiens un objet soigné qui contient le code d'état http de l'appel API et les données de l'utilisateur nouvellement créé.

Exemple:

{'ResponseMetadata': 
      {'HTTPStatusCode': 200, 
       'RequestId': 'omitted'
      },
 u'User': {u'Arn': 'arn:aws:iam::omitted:user/omitted',
           u'CreateDate': datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()),
           u'Path': '/',
           u'UserId': 'omitted',
           u'UserName': 'omitted'
          }
}

Cela fonctionne très bien. Mais lorsque cela échoue (comme si l'utilisateur existe déjà), je reçois simplement un objet de type botocore.exceptions.ClientError avec uniquement du texte pour me dire ce qui ne va pas.

Exemple: ClientError ('Une erreur s'est produite (EntityAlreadyExists) lors de l'appel de l'opération CreateUser: l'utilisateur avec un nom omis existe déjà.',)

Cela (AFAIK) rend la gestion des erreurs très difficile car je ne peux pas simplement activer le code d'état http résultant (409 pour l'utilisateur existe déjà selon les documents de l'API AWS pour IAM). Cela me fait penser que je dois faire quelque chose dans le mauvais sens. La manière optimale serait que boto3 ne lève jamais d'exceptions, mais les juts retournent toujours un objet qui reflète le déroulement de l'appel d'API.

Quelqu'un peut-il m'éclairer sur cette question ou me diriger dans la bonne direction?

SQDK
la source
3
Documents
nu everest

Réponses:

415

Utilisez la réponse contenue dans l'exception. Voici un exemple:

import boto3
from botocore.exceptions import ClientError

try:
    iam = boto3.client('iam')
    user = iam.create_user(UserName='fred')
    print("Created user: %s" % user)
except ClientError as e:
    if e.response['Error']['Code'] == 'EntityAlreadyExists':
        print("User already exists")
    else:
        print("Unexpected error: %s" % e)

Le dict de réponse dans l'exception contiendra les éléments suivants:

  • ['Error']['Code'] par exemple 'EntityAlreadyExists' ou 'ValidationError'
  • ['ResponseMetadata']['HTTPStatusCode'] par exemple 400
  • ['ResponseMetadata']['RequestId'] par exemple «d2b06652-88d7-11e5-99d0-812348583a35»
  • ['Error']['Message'] par exemple "Une erreur s'est produite (EntityAlreadyExists) ..."
  • ['Error']['Type'] par exemple "Expéditeur"

Pour plus d'informations, voir Gestion des erreurs botocore .

[Mise à jour: 2018-03-07]

Le kit SDK AWS Python a commencé à exposer des exceptions de service sur les clients (mais pas sur les ressources ) que vous pouvez explicitement intercepter, il est donc maintenant possible d'écrire ce code quelque chose comme ceci:

import boto3
from botocore.exceptions import ClientError, ParamValidationError

try:
    iam = boto3.client('iam')
    user = iam.create_user(UserName='fred')
    print("Created user: %s" % user)
except iam.exceptions.EntityAlreadyExistsException:
    print("User already exists")
except ParamValidationError as e:
    print("Parameter validation error: %s" % e)
except ClientError as e:
    print("Unexpected error: %s" % e)

Malheureusement, il n'existe actuellement aucune documentation pour ces exceptions.

jarmod
la source
2
lors de l'utilisation du client, devons-nous vérifier HTTPStatusCode dans la réponse resp ["ResponseMetadata"]. get ("HTTPStatusCode")! = 200? Je veux dire que l'api lève toujours une exception si le code d'état n'est pas 200?
himanshu219
1
@ himanshu219 Bonne question. Il n'y a aucune indication claire à ce sujet et une recherche de HTTPStatusCode dans les documents boto3 ne donne aucun résultat. D'après mon expérience, cependant, vous pouvez compter sur une exception levée.
jarmod
1
Dans tous les cas, vous ne devez pas l'utiliser uniquement 200 dans votre chèque, car le code de retour peut être un 2xxcode d'état HTTP différent (par exemple, 204lors de la suppression d'un coffre-fort ou d'une archive, 201lors de la création, etc.). Au mieux, on devrait vérifier un code non-4xx (par exemple, statusCode < 400) mais c'est vraiment fragile et je ne le recommanderais pas de toute façon: il vaut mieux se fier à botolever des exceptions sur votre code.
Marco Massenzio
24

Je l'ai trouvé très utile, car les exceptions ne sont pas documentées, pour répertorier toutes les exceptions à l'écran pour ce package. Voici le code que j'ai utilisé pour le faire:

import botocore.exceptions
def listexns(mod):
    #module = __import__(mod)
    exns = []
    for name in botocore.exceptions.__dict__:
        if (isinstance(botocore.exceptions.__dict__[name], Exception) or
            name.endswith('Error')):
            exns.append(name)
    for name in exns:
        print('%s.%s is an exception type' % (str(mod), name))
    return

if __name__ == '__main__':
    import sys
    if len(sys.argv) <= 1:
        print('Give me a module name on the $PYTHONPATH!')
    print('Looking for exception types in module: %s' % sys.argv[1])
    listexns(sys.argv[1])

Ce qui se traduit par:

Looking for exception types in module: boto3
boto3.BotoCoreError is an exception type
boto3.DataNotFoundError is an exception type
boto3.UnknownServiceError is an exception type
boto3.ApiVersionNotFoundError is an exception type
boto3.HTTPClientError is an exception type
boto3.ConnectionError is an exception type
boto3.EndpointConnectionError is an exception type
boto3.SSLError is an exception type
boto3.ConnectionClosedError is an exception type
boto3.ReadTimeoutError is an exception type
boto3.ConnectTimeoutError is an exception type
boto3.ProxyConnectionError is an exception type
boto3.NoCredentialsError is an exception type
boto3.PartialCredentialsError is an exception type
boto3.CredentialRetrievalError is an exception type
boto3.UnknownSignatureVersionError is an exception type
boto3.ServiceNotInRegionError is an exception type
boto3.BaseEndpointResolverError is an exception type
boto3.NoRegionError is an exception type
boto3.UnknownEndpointError is an exception type
boto3.ConfigParseError is an exception type
boto3.MissingParametersError is an exception type
boto3.ValidationError is an exception type
boto3.ParamValidationError is an exception type
boto3.UnknownKeyError is an exception type
boto3.RangeError is an exception type
boto3.UnknownParameterError is an exception type
boto3.AliasConflictParameterError is an exception type
boto3.PaginationError is an exception type
boto3.OperationNotPageableError is an exception type
boto3.ChecksumError is an exception type
boto3.UnseekableStreamError is an exception type
boto3.WaiterError is an exception type
boto3.IncompleteReadError is an exception type
boto3.InvalidExpressionError is an exception type
boto3.UnknownCredentialError is an exception type
boto3.WaiterConfigError is an exception type
boto3.UnknownClientMethodError is an exception type
boto3.UnsupportedSignatureVersionError is an exception type
boto3.ClientError is an exception type
boto3.EventStreamError is an exception type
boto3.InvalidDNSNameError is an exception type
boto3.InvalidS3AddressingStyleError is an exception type
boto3.InvalidRetryConfigurationError is an exception type
boto3.InvalidMaxRetryAttemptsError is an exception type
boto3.StubResponseError is an exception type
boto3.StubAssertionError is an exception type
boto3.UnStubbedResponseError is an exception type
boto3.InvalidConfigError is an exception type
boto3.InfiniteLoopConfigError is an exception type
boto3.RefreshWithMFAUnsupportedError is an exception type
boto3.MD5UnavailableError is an exception type
boto3.MetadataRetrievalError is an exception type
boto3.UndefinedModelAttributeError is an exception type
boto3.MissingServiceIdError is an exception type
jamescampbell
la source
20

Juste une mise à jour du problème `` aucune exception sur les ressources '' comme indiqué par @jarmod (n'hésitez pas à mettre à jour votre réponse si ci-dessous semble applicable)

J'ai testé le code ci-dessous et il fonctionne très bien. Il utilise des `` ressources '' pour faire des choses, mais attrape le client.exceptions- bien qu'il `` semble '' quelque peu faux ... il teste bien, les classes d'exception s'affichent et correspondent quand on regarde l'utilisation du débogueur au moment de l'exception ...

Il peut ne pas être applicable à toutes les ressources et tous les clients, mais fonctionne pour les dossiers de données (aussi appelés compartiments s3).

lab_session = boto3.Session() 
c = lab_session.client('s3') #this client is only for exception catching

try:
    b = s3.Bucket(bucket)
    b.delete()
except c.exceptions.NoSuchBucket as e:
    #ignoring no such bucket exceptions
    logger.debug("Failed deleting bucket. Continuing. {}".format(e))
except Exception as e:
    #logging all the others as warning
    logger.warning("Failed deleting bucket. Continuing. {}".format(e))

J'espère que cela t'aides...

R. Simac
la source
7
FYI: cela peut être accompli sans prédéfinir un client en utilisant:s3.meta.client.exceptions.NoSuchBucket
theY4Kman
1
qu'est-ce que s3 ici?
Sid
s3est la ressource de service, par exemple s3 = boto3.resource('s3'). Fonctionne également pour les ressources réelles, telles que les seaux:boto3.resource('s3').Bucket('bucket-name').meta.client.exceptions. ...
Czechnology
4

Comme quelques autres déjà mentionnés, vous pouvez intercepter certaines erreurs en utilisant le service client ( service_client.exceptions.<ExceptionClass>) ou la ressource ( service_resource.meta.client.exceptions.<ExceptionClass>), mais elles ne sont pas bien documentées (aussi quelles exceptions appartiennent à quels clients). Voici donc comment obtenir la cartographie complète au moment de la rédaction (janvier 2020) dans la région UE (Irlande) ( eu-west-1):

import boto3, pprint

region_name = 'eu-west-1'
session = boto3.Session(region_name=region_name)
exceptions = {
  service: list(boto3.client('sts').exceptions._code_to_exception)
  for service in session.get_available_services()
}
pprint.pprint(exceptions, width=20000)

Voici un sous-ensemble du document assez volumineux:

{'acm': ['InvalidArnException', 'InvalidDomainValidationOptionsException', 'InvalidStateException', 'InvalidTagException', 'LimitExceededException', 'RequestInProgressException', 'ResourceInUseException', 'ResourceNotFoundException', 'TooManyTagsException'],
 'apigateway': ['BadRequestException', 'ConflictException', 'LimitExceededException', 'NotFoundException', 'ServiceUnavailableException', 'TooManyRequestsException', 'UnauthorizedException'],
 'athena': ['InternalServerException', 'InvalidRequestException', 'TooManyRequestsException'],
 'autoscaling': ['AlreadyExists', 'InvalidNextToken', 'LimitExceeded', 'ResourceContention', 'ResourceInUse', 'ScalingActivityInProgress', 'ServiceLinkedRoleFailure'],
 'cloudformation': ['AlreadyExistsException', 'ChangeSetNotFound', 'CreatedButModifiedException', 'InsufficientCapabilitiesException', 'InvalidChangeSetStatus', 'InvalidOperationException', 'LimitExceededException', 'NameAlreadyExistsException', 'OperationIdAlreadyExistsException', 'OperationInProgressException', 'OperationNotFoundException', 'StackInstanceNotFoundException', 'StackSetNotEmptyException', 'StackSetNotFoundException', 'StaleRequestException', 'TokenAlreadyExistsException'],
 'cloudfront': ['AccessDenied', 'BatchTooLarge', 'CNAMEAlreadyExists', 'CannotChangeImmutablePublicKeyFields', 'CloudFrontOriginAccessIdentityAlreadyExists', 'CloudFrontOriginAccessIdentityInUse', 'DistributionAlreadyExists', 'DistributionNotDisabled', 'FieldLevelEncryptionConfigAlreadyExists', 'FieldLevelEncryptionConfigInUse', 'FieldLevelEncryptionProfileAlreadyExists', 'FieldLevelEncryptionProfileInUse', 'FieldLevelEncryptionProfileSizeExceeded', 'IllegalFieldLevelEncryptionConfigAssociationWithCacheBehavior', 'IllegalUpdate', 'InconsistentQuantities', 'InvalidArgument', 'InvalidDefaultRootObject', 'InvalidErrorCode', 'InvalidForwardCookies', 'InvalidGeoRestrictionParameter', 'InvalidHeadersForS3Origin', 'InvalidIfMatchVersion', 'InvalidLambdaFunctionAssociation', 'InvalidLocationCode', 'InvalidMinimumProtocolVersion', 'InvalidOrigin', 'InvalidOriginAccessIdentity', 'InvalidOriginKeepaliveTimeout', 'InvalidOriginReadTimeout', 'InvalidProtocolSettings', 'InvalidQueryStringParameters', 'InvalidRelativePath', 'InvalidRequiredProtocol', 'InvalidResponseCode', 'InvalidTTLOrder', 'InvalidTagging', 'InvalidViewerCertificate', 'InvalidWebACLId', 'MissingBody', 'NoSuchCloudFrontOriginAccessIdentity', 'NoSuchDistribution', 'NoSuchFieldLevelEncryptionConfig', 'NoSuchFieldLevelEncryptionProfile', 'NoSuchInvalidation', 'NoSuchOrigin', 'NoSuchPublicKey', 'NoSuchResource', 'NoSuchStreamingDistribution', 'PreconditionFailed', 'PublicKeyAlreadyExists', 'PublicKeyInUse', 'QueryArgProfileEmpty', 'StreamingDistributionAlreadyExists', 'StreamingDistributionNotDisabled', 'TooManyCacheBehaviors', 'TooManyCertificates', 'TooManyCloudFrontOriginAccessIdentities', 'TooManyCookieNamesInWhiteList', 'TooManyDistributionCNAMEs', 'TooManyDistributions', 'TooManyDistributionsAssociatedToFieldLevelEncryptionConfig', 'TooManyDistributionsWithLambdaAssociations', 'TooManyFieldLevelEncryptionConfigs', 'TooManyFieldLevelEncryptionContentTypeProfiles', 'TooManyFieldLevelEncryptionEncryptionEntities', 'TooManyFieldLevelEncryptionFieldPatterns', 'TooManyFieldLevelEncryptionProfiles', 'TooManyFieldLevelEncryptionQueryArgProfiles', 'TooManyHeadersInForwardedValues', 'TooManyInvalidationsInProgress', 'TooManyLambdaFunctionAssociations', 'TooManyOriginCustomHeaders', 'TooManyOriginGroupsPerDistribution', 'TooManyOrigins', 'TooManyPublicKeys', 'TooManyQueryStringParameters', 'TooManyStreamingDistributionCNAMEs', 'TooManyStreamingDistributions', 'TooManyTrustedSigners', 'TrustedSignerDoesNotExist'],
 'cloudtrail': ['CloudTrailARNInvalidException', 'CloudTrailAccessNotEnabledException', 'CloudWatchLogsDeliveryUnavailableException', 'InsufficientDependencyServiceAccessPermissionException', 'InsufficientEncryptionPolicyException', 'InsufficientS3BucketPolicyException', 'InsufficientSnsTopicPolicyException', 'InvalidCloudWatchLogsLogGroupArnException', 'InvalidCloudWatchLogsRoleArnException', 'InvalidEventSelectorsException', 'InvalidHomeRegionException', 'InvalidKmsKeyIdException', 'InvalidLookupAttributesException', 'InvalidMaxResultsException', 'InvalidNextTokenException', 'InvalidParameterCombinationException', 'InvalidS3BucketNameException', 'InvalidS3PrefixException', 'InvalidSnsTopicNameException', 'InvalidTagParameterException', 'InvalidTimeRangeException', 'InvalidTokenException', 'InvalidTrailNameException', 'KmsException', 'KmsKeyDisabledException', 'KmsKeyNotFoundException', 'MaximumNumberOfTrailsExceededException', 'NotOrganizationMasterAccountException', 'OperationNotPermittedException', 'OrganizationNotInAllFeaturesModeException', 'OrganizationsNotInUseException', 'ResourceNotFoundException', 'ResourceTypeNotSupportedException', 'S3BucketDoesNotExistException', 'TagsLimitExceededException', 'TrailAlreadyExistsException', 'TrailNotFoundException', 'TrailNotProvidedException', 'UnsupportedOperationException'],
 'cloudwatch': ['InvalidParameterInput', 'ResourceNotFound', 'InternalServiceError', 'InvalidFormat', 'InvalidNextToken', 'InvalidParameterCombination', 'InvalidParameterValue', 'LimitExceeded', 'MissingParameter'],
 'codebuild': ['AccountLimitExceededException', 'InvalidInputException', 'OAuthProviderException', 'ResourceAlreadyExistsException', 'ResourceNotFoundException'],
 'config': ['InsufficientDeliveryPolicyException', 'InsufficientPermissionsException', 'InvalidConfigurationRecorderNameException', 'InvalidDeliveryChannelNameException', 'InvalidLimitException', 'InvalidNextTokenException', 'InvalidParameterValueException', 'InvalidRecordingGroupException', 'InvalidResultTokenException', 'InvalidRoleException', 'InvalidS3KeyPrefixException', 'InvalidSNSTopicARNException', 'InvalidTimeRangeException', 'LastDeliveryChannelDeleteFailedException', 'LimitExceededException', 'MaxNumberOfConfigRulesExceededException', 'MaxNumberOfConfigurationRecordersExceededException', 'MaxNumberOfDeliveryChannelsExceededException', 'MaxNumberOfRetentionConfigurationsExceededException', 'NoAvailableConfigurationRecorderException', 'NoAvailableDeliveryChannelException', 'NoAvailableOrganizationException', 'NoRunningConfigurationRecorderException', 'NoSuchBucketException', 'NoSuchConfigRuleException', 'NoSuchConfigurationAggregatorException', 'NoSuchConfigurationRecorderException', 'NoSuchDeliveryChannelException', 'NoSuchRetentionConfigurationException', 'OrganizationAccessDeniedException', 'OrganizationAllFeaturesNotEnabledException', 'OversizedConfigurationItemException', 'ResourceInUseException', 'ResourceNotDiscoveredException', 'ValidationException'],
 'dynamodb': ['BackupInUseException', 'BackupNotFoundException', 'ConditionalCheckFailedException', 'ContinuousBackupsUnavailableException', 'GlobalTableAlreadyExistsException', 'GlobalTableNotFoundException', 'IdempotentParameterMismatchException', 'IndexNotFoundException', 'InternalServerError', 'InvalidRestoreTimeException', 'ItemCollectionSizeLimitExceededException', 'LimitExceededException', 'PointInTimeRecoveryUnavailableException', 'ProvisionedThroughputExceededException', 'ReplicaAlreadyExistsException', 'ReplicaNotFoundException', 'RequestLimitExceeded', 'ResourceInUseException', 'ResourceNotFoundException', 'TableAlreadyExistsException', 'TableInUseException', 'TableNotFoundException', 'TransactionCanceledException', 'TransactionConflictException', 'TransactionInProgressException'],
 'ec2': [],
 'ecr': ['EmptyUploadException', 'ImageAlreadyExistsException', 'ImageNotFoundException', 'InvalidLayerException', 'InvalidLayerPartException', 'InvalidParameterException', 'InvalidTagParameterException', 'LayerAlreadyExistsException', 'LayerInaccessibleException', 'LayerPartTooSmallException', 'LayersNotFoundException', 'LifecyclePolicyNotFoundException', 'LifecyclePolicyPreviewInProgressException', 'LifecyclePolicyPreviewNotFoundException', 'LimitExceededException', 'RepositoryAlreadyExistsException', 'RepositoryNotEmptyException', 'RepositoryNotFoundException', 'RepositoryPolicyNotFoundException', 'ServerException', 'TooManyTagsException', 'UploadNotFoundException'],
 'ecs': ['AccessDeniedException', 'AttributeLimitExceededException', 'BlockedException', 'ClientException', 'ClusterContainsContainerInstancesException', 'ClusterContainsServicesException', 'ClusterContainsTasksException', 'ClusterNotFoundException', 'InvalidParameterException', 'MissingVersionException', 'NoUpdateAvailableException', 'PlatformTaskDefinitionIncompatibilityException', 'PlatformUnknownException', 'ResourceNotFoundException', 'ServerException', 'ServiceNotActiveException', 'ServiceNotFoundException', 'TargetNotFoundException', 'UnsupportedFeatureException', 'UpdateInProgressException'],
 'efs': ['BadRequest', 'DependencyTimeout', 'FileSystemAlreadyExists', 'FileSystemInUse', 'FileSystemLimitExceeded', 'FileSystemNotFound', 'IncorrectFileSystemLifeCycleState', 'IncorrectMountTargetState', 'InsufficientThroughputCapacity', 'InternalServerError', 'IpAddressInUse', 'MountTargetConflict', 'MountTargetNotFound', 'NetworkInterfaceLimitExceeded', 'NoFreeAddressesInSubnet', 'SecurityGroupLimitExceeded', 'SecurityGroupNotFound', 'SubnetNotFound', 'ThroughputLimitExceeded', 'TooManyRequests', 'UnsupportedAvailabilityZone'],
 'eks': ['ClientException', 'InvalidParameterException', 'InvalidRequestException', 'ResourceInUseException', 'ResourceLimitExceededException', 'ResourceNotFoundException', 'ServerException', 'ServiceUnavailableException', 'UnsupportedAvailabilityZoneException'],
 'elasticache': ['APICallRateForCustomerExceeded', 'AuthorizationAlreadyExists', 'AuthorizationNotFound', 'CacheClusterAlreadyExists', 'CacheClusterNotFound', 'CacheParameterGroupAlreadyExists', 'CacheParameterGroupNotFound', 'CacheParameterGroupQuotaExceeded', 'CacheSecurityGroupAlreadyExists', 'CacheSecurityGroupNotFound', 'QuotaExceeded.CacheSecurityGroup', 'CacheSubnetGroupAlreadyExists', 'CacheSubnetGroupInUse', 'CacheSubnetGroupNotFoundFault', 'CacheSubnetGroupQuotaExceeded', 'CacheSubnetQuotaExceededFault', 'ClusterQuotaForCustomerExceeded', 'InsufficientCacheClusterCapacity', 'InvalidARN', 'InvalidCacheClusterState', 'InvalidCacheParameterGroupState', 'InvalidCacheSecurityGroupState', 'InvalidParameterCombination', 'InvalidParameterValue', 'InvalidReplicationGroupState', 'InvalidSnapshotState', 'InvalidSubnet', 'InvalidVPCNetworkStateFault', 'NoOperationFault', 'NodeGroupNotFoundFault', 'NodeGroupsPerReplicationGroupQuotaExceeded', 'NodeQuotaForClusterExceeded', 'NodeQuotaForCustomerExceeded', 'ReplicationGroupAlreadyExists', 'ReplicationGroupNotFoundFault', 'ReservedCacheNodeAlreadyExists', 'ReservedCacheNodeNotFound', 'ReservedCacheNodeQuotaExceeded', 'ReservedCacheNodesOfferingNotFound', 'ServiceLinkedRoleNotFoundFault', 'SnapshotAlreadyExistsFault', 'SnapshotFeatureNotSupportedFault', 'SnapshotNotFoundFault', 'SnapshotQuotaExceededFault', 'SubnetInUse', 'TagNotFound', 'TagQuotaPerResourceExceeded', 'TestFailoverNotAvailableFault'],
 'elasticbeanstalk': ['CodeBuildNotInServiceRegionException', 'ElasticBeanstalkServiceException', 'InsufficientPrivilegesException', 'InvalidRequestException', 'ManagedActionInvalidStateException', 'OperationInProgressFailure', 'PlatformVersionStillReferencedException', 'ResourceNotFoundException', 'ResourceTypeNotSupportedException', 'S3LocationNotInServiceRegionException', 'S3SubscriptionRequiredException', 'SourceBundleDeletionFailure', 'TooManyApplicationVersionsException', 'TooManyApplicationsException', 'TooManyBucketsException', 'TooManyConfigurationTemplatesException', 'TooManyEnvironmentsException', 'TooManyPlatformsException', 'TooManyTagsException'],
 'elb': ['LoadBalancerNotFound', 'CertificateNotFound', 'DependencyThrottle', 'DuplicateLoadBalancerName', 'DuplicateListener', 'DuplicatePolicyName', 'DuplicateTagKeys', 'InvalidConfigurationRequest', 'InvalidInstance', 'InvalidScheme', 'InvalidSecurityGroup', 'InvalidSubnet', 'ListenerNotFound', 'LoadBalancerAttributeNotFound', 'OperationNotPermitted', 'PolicyNotFound', 'PolicyTypeNotFound', 'SubnetNotFound', 'TooManyLoadBalancers', 'TooManyPolicies', 'TooManyTags', 'UnsupportedProtocol'],
 'emr': ['InternalServerError', 'InternalServerException', 'InvalidRequestException'],
 'es': ['BaseException', 'DisabledOperationException', 'InternalException', 'InvalidTypeException', 'LimitExceededException', 'ResourceAlreadyExistsException', 'ResourceNotFoundException', 'ValidationException'],
 'events': ['ConcurrentModificationException', 'InternalException', 'InvalidEventPatternException', 'LimitExceededException', 'ManagedRuleException', 'PolicyLengthExceededException', 'ResourceNotFoundException'],
 'firehose': ['ConcurrentModificationException', 'InvalidArgumentException', 'LimitExceededException', 'ResourceInUseException', 'ResourceNotFoundException', 'ServiceUnavailableException'],
 'glacier': ['InsufficientCapacityException', 'InvalidParameterValueException', 'LimitExceededException', 'MissingParameterValueException', 'PolicyEnforcedException', 'RequestTimeoutException', 'ResourceNotFoundException', 'ServiceUnavailableException'],
 'glue': ['AccessDeniedException', 'AlreadyExistsException', 'ConcurrentModificationException', 'ConcurrentRunsExceededException', 'ConditionCheckFailureException', 'CrawlerNotRunningException', 'CrawlerRunningException', 'CrawlerStoppingException', 'EntityNotFoundException', 'GlueEncryptionException', 'IdempotentParameterMismatchException', 'InternalServiceException', 'InvalidInputException', 'NoScheduleException', 'OperationTimeoutException', 'ResourceNumberLimitExceededException', 'SchedulerNotRunningException', 'SchedulerRunningException', 'SchedulerTransitioningException', 'ValidationException', 'VersionMismatchException'],
 'iam': ['ConcurrentModification', 'ReportExpired', 'ReportNotPresent', 'ReportInProgress', 'DeleteConflict', 'DuplicateCertificate', 'DuplicateSSHPublicKey', 'EntityAlreadyExists', 'EntityTemporarilyUnmodifiable', 'InvalidAuthenticationCode', 'InvalidCertificate', 'InvalidInput', 'InvalidPublicKey', 'InvalidUserType', 'KeyPairMismatch', 'LimitExceeded', 'MalformedCertificate', 'MalformedPolicyDocument', 'NoSuchEntity', 'PasswordPolicyViolation', 'PolicyEvaluation', 'PolicyNotAttachable', 'ServiceFailure', 'NotSupportedService', 'UnmodifiableEntity', 'UnrecognizedPublicKeyEncoding'],
 'kinesis': ['ExpiredIteratorException', 'ExpiredNextTokenException', 'InternalFailureException', 'InvalidArgumentException', 'KMSAccessDeniedException', 'KMSDisabledException', 'KMSInvalidStateException', 'KMSNotFoundException', 'KMSOptInRequired', 'KMSThrottlingException', 'LimitExceededException', 'ProvisionedThroughputExceededException', 'ResourceInUseException', 'ResourceNotFoundException'],
 'kms': ['AlreadyExistsException', 'CloudHsmClusterInUseException', 'CloudHsmClusterInvalidConfigurationException', 'CloudHsmClusterNotActiveException', 'CloudHsmClusterNotFoundException', 'CloudHsmClusterNotRelatedException', 'CustomKeyStoreHasCMKsException', 'CustomKeyStoreInvalidStateException', 'CustomKeyStoreNameInUseException', 'CustomKeyStoreNotFoundException', 'DependencyTimeoutException', 'DisabledException', 'ExpiredImportTokenException', 'IncorrectKeyMaterialException', 'IncorrectTrustAnchorException', 'InvalidAliasNameException', 'InvalidArnException', 'InvalidCiphertextException', 'InvalidGrantIdException', 'InvalidGrantTokenException', 'InvalidImportTokenException', 'InvalidKeyUsageException', 'InvalidMarkerException', 'KMSInternalException', 'KMSInvalidStateException', 'KeyUnavailableException', 'LimitExceededException', 'MalformedPolicyDocumentException', 'NotFoundException', 'TagException', 'UnsupportedOperationException'],
 'lambda': ['CodeStorageExceededException', 'EC2AccessDeniedException', 'EC2ThrottledException', 'EC2UnexpectedException', 'ENILimitReachedException', 'InvalidParameterValueException', 'InvalidRequestContentException', 'InvalidRuntimeException', 'InvalidSecurityGroupIDException', 'InvalidSubnetIDException', 'InvalidZipFileException', 'KMSAccessDeniedException', 'KMSDisabledException', 'KMSInvalidStateException', 'KMSNotFoundException', 'PolicyLengthExceededException', 'PreconditionFailedException', 'RequestTooLargeException', 'ResourceConflictException', 'ResourceInUseException', 'ResourceNotFoundException', 'ServiceException', 'SubnetIPAddressLimitReachedException', 'TooManyRequestsException', 'UnsupportedMediaTypeException'],
 'logs': ['DataAlreadyAcceptedException', 'InvalidOperationException', 'InvalidParameterException', 'InvalidSequenceTokenException', 'LimitExceededException', 'MalformedQueryException', 'OperationAbortedException', 'ResourceAlreadyExistsException', 'ResourceNotFoundException', 'ServiceUnavailableException', 'UnrecognizedClientException'],
 'neptune': ['AuthorizationNotFound', 'CertificateNotFound', 'DBClusterAlreadyExistsFault', 'DBClusterNotFoundFault', 'DBClusterParameterGroupNotFound', 'DBClusterQuotaExceededFault', 'DBClusterRoleAlreadyExists', 'DBClusterRoleNotFound', 'DBClusterRoleQuotaExceeded', 'DBClusterSnapshotAlreadyExistsFault', 'DBClusterSnapshotNotFoundFault', 'DBInstanceAlreadyExists', 'DBInstanceNotFound', 'DBParameterGroupAlreadyExists', 'DBParameterGroupNotFound', 'DBParameterGroupQuotaExceeded', 'DBSecurityGroupNotFound', 'DBSnapshotAlreadyExists', 'DBSnapshotNotFound', 'DBSubnetGroupAlreadyExists', 'DBSubnetGroupDoesNotCoverEnoughAZs', 'DBSubnetGroupNotFoundFault', 'DBSubnetGroupQuotaExceeded', 'DBSubnetQuotaExceededFault', 'DBUpgradeDependencyFailure', 'DomainNotFoundFault', 'EventSubscriptionQuotaExceeded', 'InstanceQuotaExceeded', 'InsufficientDBClusterCapacityFault', 'InsufficientDBInstanceCapacity', 'InsufficientStorageClusterCapacity', 'InvalidDBClusterSnapshotStateFault', 'InvalidDBClusterStateFault', 'InvalidDBInstanceState', 'InvalidDBParameterGroupState', 'InvalidDBSecurityGroupState', 'InvalidDBSnapshotState', 'InvalidDBSubnetGroupStateFault', 'InvalidDBSubnetStateFault', 'InvalidEventSubscriptionState', 'InvalidRestoreFault', 'InvalidSubnet', 'InvalidVPCNetworkStateFault', 'KMSKeyNotAccessibleFault', 'OptionGroupNotFoundFault', 'ProvisionedIopsNotAvailableInAZFault', 'ResourceNotFoundFault', 'SNSInvalidTopic', 'SNSNoAuthorization', 'SNSTopicArnNotFound', 'SharedSnapshotQuotaExceeded', 'SnapshotQuotaExceeded', 'SourceNotFound', 'StorageQuotaExceeded', 'StorageTypeNotSupported', 'SubnetAlreadyInUse', 'SubscriptionAlreadyExist', 'SubscriptionCategoryNotFound', 'SubscriptionNotFound'],
 'rds': ['AuthorizationAlreadyExists', 'AuthorizationNotFound', 'AuthorizationQuotaExceeded', 'BackupPolicyNotFoundFault', 'CertificateNotFound', 'DBClusterAlreadyExistsFault', 'DBClusterBacktrackNotFoundFault', 'DBClusterEndpointAlreadyExistsFault', 'DBClusterEndpointNotFoundFault', 'DBClusterEndpointQuotaExceededFault', 'DBClusterNotFoundFault', 'DBClusterParameterGroupNotFound', 'DBClusterQuotaExceededFault', 'DBClusterRoleAlreadyExists', 'DBClusterRoleNotFound', 'DBClusterRoleQuotaExceeded', 'DBClusterSnapshotAlreadyExistsFault', 'DBClusterSnapshotNotFoundFault', 'DBInstanceAlreadyExists', 'DBInstanceAutomatedBackupNotFound', 'DBInstanceAutomatedBackupQuotaExceeded', 'DBInstanceNotFound', 'DBInstanceRoleAlreadyExists', 'DBInstanceRoleNotFound', 'DBInstanceRoleQuotaExceeded', 'DBLogFileNotFoundFault', 'DBParameterGroupAlreadyExists', 'DBParameterGroupNotFound', 'DBParameterGroupQuotaExceeded', 'DBSecurityGroupAlreadyExists', 'DBSecurityGroupNotFound', 'DBSecurityGroupNotSupported', 'QuotaExceeded.DBSecurityGroup', 'DBSnapshotAlreadyExists', 'DBSnapshotNotFound', 'DBSubnetGroupAlreadyExists', 'DBSubnetGroupDoesNotCoverEnoughAZs', 'DBSubnetGroupNotAllowedFault', 'DBSubnetGroupNotFoundFault', 'DBSubnetGroupQuotaExceeded', 'DBSubnetQuotaExceededFault', 'DBUpgradeDependencyFailure', 'DomainNotFoundFault', 'EventSubscriptionQuotaExceeded', 'GlobalClusterAlreadyExistsFault', 'GlobalClusterNotFoundFault', 'GlobalClusterQuotaExceededFault', 'InstanceQuotaExceeded', 'InsufficientDBClusterCapacityFault', 'InsufficientDBInstanceCapacity', 'InsufficientStorageClusterCapacity', 'InvalidDBClusterCapacityFault', 'InvalidDBClusterEndpointStateFault', 'InvalidDBClusterSnapshotStateFault', 'InvalidDBClusterStateFault', 'InvalidDBInstanceAutomatedBackupState', 'InvalidDBInstanceState', 'InvalidDBParameterGroupState', 'InvalidDBSecurityGroupState', 'InvalidDBSnapshotState', 'InvalidDBSubnetGroupFault', 'InvalidDBSubnetGroupStateFault', 'InvalidDBSubnetStateFault', 'InvalidEventSubscriptionState', 'InvalidGlobalClusterStateFault', 'InvalidOptionGroupStateFault', 'InvalidRestoreFault', 'InvalidS3BucketFault', 'InvalidSubnet', 'InvalidVPCNetworkStateFault', 'KMSKeyNotAccessibleFault', 'OptionGroupAlreadyExistsFault', 'OptionGroupNotFoundFault', 'OptionGroupQuotaExceededFault', 'PointInTimeRestoreNotEnabled', 'ProvisionedIopsNotAvailableInAZFault', 'ReservedDBInstanceAlreadyExists', 'ReservedDBInstanceNotFound', 'ReservedDBInstanceQuotaExceeded', 'ReservedDBInstancesOfferingNotFound', 'ResourceNotFoundFault', 'SNSInvalidTopic', 'SNSNoAuthorization', 'SNSTopicArnNotFound', 'SharedSnapshotQuotaExceeded', 'SnapshotQuotaExceeded', 'SourceNotFound', 'StorageQuotaExceeded', 'StorageTypeNotSupported', 'SubnetAlreadyInUse', 'SubscriptionAlreadyExist', 'SubscriptionCategoryNotFound', 'SubscriptionNotFound'],
 'route53': ['ConcurrentModification', 'ConflictingDomainExists', 'ConflictingTypes', 'DelegationSetAlreadyCreated', 'DelegationSetAlreadyReusable', 'DelegationSetInUse', 'DelegationSetNotAvailable', 'DelegationSetNotReusable', 'HealthCheckAlreadyExists', 'HealthCheckInUse', 'HealthCheckVersionMismatch', 'HostedZoneAlreadyExists', 'HostedZoneNotEmpty', 'HostedZoneNotFound', 'HostedZoneNotPrivate', 'IncompatibleVersion', 'InsufficientCloudWatchLogsResourcePolicy', 'InvalidArgument', 'InvalidChangeBatch', 'InvalidDomainName', 'InvalidInput', 'InvalidPaginationToken', 'InvalidTrafficPolicyDocument', 'InvalidVPCId', 'LastVPCAssociation', 'LimitsExceeded', 'NoSuchChange', 'NoSuchCloudWatchLogsLogGroup', 'NoSuchDelegationSet', 'NoSuchGeoLocation', 'NoSuchHealthCheck', 'NoSuchHostedZone', 'NoSuchQueryLoggingConfig', 'NoSuchTrafficPolicy', 'NoSuchTrafficPolicyInstance', 'NotAuthorizedException', 'PriorRequestNotComplete', 'PublicZoneVPCAssociation', 'QueryLoggingConfigAlreadyExists', 'ThrottlingException', 'TooManyHealthChecks', 'TooManyHostedZones', 'TooManyTrafficPolicies', 'TooManyTrafficPolicyInstances', 'TooManyTrafficPolicyVersionsForCurrentPolicy', 'TooManyVPCAssociationAuthorizations', 'TrafficPolicyAlreadyExists', 'TrafficPolicyInUse', 'TrafficPolicyInstanceAlreadyExists', 'VPCAssociationAuthorizationNotFound', 'VPCAssociationNotFound'],
 's3': ['BucketAlreadyExists', 'BucketAlreadyOwnedByYou', 'NoSuchBucket', 'NoSuchKey', 'NoSuchUpload', 'ObjectAlreadyInActiveTierError', 'ObjectNotInActiveTierError'],
 'sagemaker': ['ResourceInUse', 'ResourceLimitExceeded', 'ResourceNotFound'],
 'secretsmanager': ['DecryptionFailure', 'EncryptionFailure', 'InternalServiceError', 'InvalidNextTokenException', 'InvalidParameterException', 'InvalidRequestException', 'LimitExceededException', 'MalformedPolicyDocumentException', 'PreconditionNotMetException', 'ResourceExistsException', 'ResourceNotFoundException'],
 'ses': ['AccountSendingPausedException', 'AlreadyExists', 'CannotDelete', 'ConfigurationSetAlreadyExists', 'ConfigurationSetDoesNotExist', 'ConfigurationSetSendingPausedException', 'CustomVerificationEmailInvalidContent', 'CustomVerificationEmailTemplateAlreadyExists', 'CustomVerificationEmailTemplateDoesNotExist', 'EventDestinationAlreadyExists', 'EventDestinationDoesNotExist', 'FromEmailAddressNotVerified', 'InvalidCloudWatchDestination', 'InvalidConfigurationSet', 'InvalidFirehoseDestination', 'InvalidLambdaFunction', 'InvalidPolicy', 'InvalidRenderingParameter', 'InvalidS3Configuration', 'InvalidSNSDestination', 'InvalidSnsTopic', 'InvalidTemplate', 'InvalidTrackingOptions', 'LimitExceeded', 'MailFromDomainNotVerifiedException', 'MessageRejected', 'MissingRenderingAttribute', 'ProductionAccessNotGranted', 'RuleDoesNotExist', 'RuleSetDoesNotExist', 'TemplateDoesNotExist', 'TrackingOptionsAlreadyExistsException', 'TrackingOptionsDoesNotExistException'],
 'sns': ['AuthorizationError', 'EndpointDisabled', 'FilterPolicyLimitExceeded', 'InternalError', 'InvalidParameter', 'ParameterValueInvalid', 'InvalidSecurity', 'KMSAccessDenied', 'KMSDisabled', 'KMSInvalidState', 'KMSNotFound', 'KMSOptInRequired', 'KMSThrottling', 'NotFound', 'PlatformApplicationDisabled', 'SubscriptionLimitExceeded', 'Throttled', 'TopicLimitExceeded'],
 'sqs': ['AWS.SimpleQueueService.BatchEntryIdsNotDistinct', 'AWS.SimpleQueueService.BatchRequestTooLong', 'AWS.SimpleQueueService.EmptyBatchRequest', 'InvalidAttributeName', 'AWS.SimpleQueueService.InvalidBatchEntryId', 'InvalidIdFormat', 'InvalidMessageContents', 'AWS.SimpleQueueService.MessageNotInflight', 'OverLimit', 'AWS.SimpleQueueService.PurgeQueueInProgress', 'AWS.SimpleQueueService.QueueDeletedRecently', 'AWS.SimpleQueueService.NonExistentQueue', 'QueueAlreadyExists', 'ReceiptHandleIsInvalid', 'AWS.SimpleQueueService.TooManyEntriesInBatchRequest', 'AWS.SimpleQueueService.UnsupportedOperation'],
 'ssm': ['AlreadyExistsException', 'AssociatedInstances', 'AssociationAlreadyExists', 'AssociationDoesNotExist', 'AssociationExecutionDoesNotExist', 'AssociationLimitExceeded', 'AssociationVersionLimitExceeded', 'AutomationDefinitionNotFoundException', 'AutomationDefinitionVersionNotFoundException', 'AutomationExecutionLimitExceededException', 'AutomationExecutionNotFoundException', 'AutomationStepNotFoundException', 'ComplianceTypeCountLimitExceededException', 'CustomSchemaCountLimitExceededException', 'DocumentAlreadyExists', 'DocumentLimitExceeded', 'DocumentPermissionLimit', 'DocumentVersionLimitExceeded', 'DoesNotExistException', 'DuplicateDocumentContent', 'DuplicateDocumentVersionName', 'DuplicateInstanceId', 'FeatureNotAvailableException', 'HierarchyLevelLimitExceededException', 'HierarchyTypeMismatchException', 'IdempotentParameterMismatch', 'InternalServerError', 'InvalidActivation', 'InvalidActivationId', 'InvalidAggregatorException', 'InvalidAllowedPatternException', 'InvalidAssociation', 'InvalidAssociationVersion', 'InvalidAutomationExecutionParametersException', 'InvalidAutomationSignalException', 'InvalidAutomationStatusUpdateException', 'InvalidCommandId', 'InvalidDeleteInventoryParametersException', 'InvalidDeletionIdException', 'InvalidDocument', 'InvalidDocumentContent', 'InvalidDocumentOperation', 'InvalidDocumentSchemaVersion', 'InvalidDocumentVersion', 'InvalidFilter', 'InvalidFilterKey', 'InvalidFilterOption', 'InvalidFilterValue', 'InvalidInstanceId', 'InvalidInstanceInformationFilterValue', 'InvalidInventoryGroupException', 'InvalidInventoryItemContextException', 'InvalidInventoryRequestException', 'InvalidItemContentException', 'InvalidKeyId', 'InvalidNextToken', 'InvalidNotificationConfig', 'InvalidOptionException', 'InvalidOutputFolder', 'InvalidOutputLocation', 'InvalidParameters', 'InvalidPermissionType', 'InvalidPluginName', 'InvalidResourceId', 'InvalidResourceType', 'InvalidResultAttributeException', 'InvalidRole', 'InvalidSchedule', 'InvalidTarget', 'InvalidTypeNameException', 'InvalidUpdate', 'InvocationDoesNotExist', 'ItemContentMismatchException', 'ItemSizeLimitExceededException', 'MaxDocumentSizeExceeded', 'ParameterAlreadyExists', 'ParameterLimitExceeded', 'ParameterMaxVersionLimitExceeded', 'ParameterNotFound', 'ParameterPatternMismatchException', 'ParameterVersionLabelLimitExceeded', 'ParameterVersionNotFound', 'ResourceDataSyncAlreadyExistsException', 'ResourceDataSyncCountExceededException', 'ResourceDataSyncInvalidConfigurationException', 'ResourceDataSyncNotFoundException', 'ResourceInUseException', 'ResourceLimitExceededException', 'StatusUnchanged', 'SubTypeCountLimitExceededException', 'TargetInUseException', 'TargetNotConnected', 'TooManyTagsError', 'TooManyUpdates', 'TotalSizeLimitExceededException', 'UnsupportedInventoryItemContextException', 'UnsupportedInventorySchemaVersionException', 'UnsupportedOperatingSystem', 'UnsupportedParameterType', 'UnsupportedPlatformType'],
 'stepfunctions': ['ActivityDoesNotExist', 'ActivityLimitExceeded', 'ActivityWorkerLimitExceeded', 'ExecutionAlreadyExists', 'ExecutionDoesNotExist', 'ExecutionLimitExceeded', 'InvalidArn', 'InvalidDefinition', 'InvalidExecutionInput', 'InvalidName', 'InvalidOutput', 'InvalidToken', 'MissingRequiredParameter', 'ResourceNotFound', 'StateMachineAlreadyExists', 'StateMachineDeleting', 'StateMachineDoesNotExist', 'StateMachineLimitExceeded', 'TaskDoesNotExist', 'TaskTimedOut', 'TooManyTags'],
 'sts': ['ExpiredTokenException', 'IDPCommunicationError', 'IDPRejectedClaim', 'InvalidAuthorizationMessageException', 'InvalidIdentityToken', 'MalformedPolicyDocument', 'PackedPolicyTooLarge', 'RegionDisabledException'],
 'xray': ['InvalidRequestException', 'RuleLimitExceededException', 'ThrottledException']}
Czechnology
la source
3

Ou une comparaison sur le nom de la classe, par exemple

except ClientError as e:
    if 'EntityAlreadyExistsException' == e.__class__.__name__:
        # handle specific error

Parce qu'ils sont créés dynamiquement, vous ne pouvez jamais importer la classe et l'attraper en utilisant du vrai Python.

jmoz
la source
Donc, j'attraperais toutes les exceptions avec except Exception as eet puis aurais des instructions if pour déterminer l'exception spécifique? En quoi est-ce différent / meilleur que la capture d'exceptions spécifiques? Ce sont plus de lignes, et vous devrez quand même importer la bibliothèque pour obtenir le nom de la classe. À moins que vous ne vouliez aller coder en dur le nom de l'exception. Dans l'ensemble, cela semble être une mauvaise façon de procéder.
SQDK
@SQDK désolé, ma réponse n'était pas claire, mais pas de quoi vous parlez. Je l'ai mis à jour.
jmoz
1

Si vous appelez l'API sign_up (AWS Cognito) à l'aide de Python3, vous pouvez utiliser le code suivant.

def registerUser(userObj):
    ''' Registers the user to AWS Cognito.
    '''

    # Mobile number is not a mandatory field. 
    if(len(userObj['user_mob_no']) == 0):
        mobilenumber = ''
    else:
        mobilenumber = userObj['user_country_code']+userObj['user_mob_no']

    secretKey = bytes(settings.SOCIAL_AUTH_COGNITO_SECRET, 'latin-1')
    clientId = settings.SOCIAL_AUTH_COGNITO_KEY 

    digest = hmac.new(secretKey,
                msg=(userObj['user_name'] + clientId).encode('utf-8'),
                digestmod=hashlib.sha256
                ).digest()
    signature = base64.b64encode(digest).decode()

    client = boto3.client('cognito-idp', region_name='eu-west-1' ) 

    try:
        response = client.sign_up(
                    ClientId=clientId,
                    Username=userObj['user_name'],
                    Password=userObj['password1'],
                    SecretHash=signature,
                    UserAttributes=[
                        {
                            'Name': 'given_name',
                            'Value': userObj['given_name']
                        },
                        {
                            'Name': 'family_name',
                            'Value': userObj['family_name']
                        },
                        {
                            'Name': 'email',
                            'Value': userObj['user_email']
                        },
                        {
                            'Name': 'phone_number',
                            'Value': mobilenumber
                        }
                    ],
                    ValidationData=[
                        {
                            'Name': 'email',
                            'Value': userObj['user_email']
                        },
                    ]
                    ,
                    AnalyticsMetadata={
                        'AnalyticsEndpointId': 'string'
                    },
                    UserContextData={
                        'EncodedData': 'string'
                    }
                )
    except ClientError as error:
        return {"errorcode": error.response['Error']['Code'],
            "errormessage" : error.response['Error']['Message'] }
    except Exception as e:
        return {"errorcode": "Something went wrong. Try later or contact the admin" }
    return {"success": "User registered successfully. "}

error.response ['Error'] ['Code'] sera InvalidPasswordException, UsernameExistsException etc. Donc, dans la fonction principale ou là où vous appelez la fonction, vous pouvez écrire la logique pour fournir un message significatif à l'utilisateur.

Un exemple pour la réponse (error.response):

{
  "Error": {
    "Message": "Password did not conform with policy: Password must have symbol characters",
    "Code": "InvalidPasswordException"
  },
  "ResponseMetadata": {
    "RequestId": "c8a591d5-8c51-4af9-8fad-b38b270c3ca2",
    "HTTPStatusCode": 400,
    "HTTPHeaders": {
      "date": "Wed, 17 Jul 2019 09:38:32 GMT",
      "content-type": "application/x-amz-json-1.1",
      "content-length": "124",
      "connection": "keep-alive",
      "x-amzn-requestid": "c8a591d5-8c51-4af9-8fad-b38b270c3ca2",
      "x-amzn-errortype": "InvalidPasswordException:",
      "x-amzn-errormessage": "Password did not conform with policy: Password must have symbol characters"
    },
    "RetryAttempts": 0
  }
}

Pour plus d'informations: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.sign_up

Haris Np
la source
1

Dans le cas où vous devez faire face au logsclient sans doute hostile ( CloudWatch Logsput-log-events ), voici ce que j'ai dû faire pour intercepter correctement les exceptions du client Boto3:

try:
    ### Boto3 client code here...

except boto_exceptions.ClientError as error:
    Log.warning("Catched client error code %s",
                error.response['Error']['Code'])

    if error.response['Error']['Code'] in ["DataAlreadyAcceptedException",
                                           "InvalidSequenceTokenException"]:
        Log.debug(
            "Fetching sequence_token from boto error response['Error']['Message'] %s",
            error.response["Error"]["Message"])
        # NOTE: apparently there's no sequenceToken attribute in the response so we have
        # to parse response["Error"]["Message"] string
        sequence_token = error.response["Error"]["Message"].split(":")[-1].strip(" ")
        Log.debug("Setting sequence_token to %s", sequence_token)

Cela fonctionne à la fois à la première tentative (avec LogStream vide) et aux suivantes.

Alexander Fortin
la source
0

Suite à la mise à jour de @ armod sur les exceptions ajoutées directement sur les clientobjets. Je vais montrer comment vous pouvez voir toutes les exceptions définies pour votre classe client.

Des exceptions sont générées dynamiquement lorsque vous créez votre client avec session.create_client()ou boto3.client(). En interne, il appelle méthode botocore.errorfactory.ClientExceptionsFactory._create_client_exceptions()et remplit le client.exceptionschamp avec des classes d'exceptions construites.

Tous les noms de classe sont disponibles dans le client.exceptions._code_to_exceptiondictionnaire, vous pouvez donc répertorier tous les types avec l'extrait de code suivant:

client = boto3.client('s3')

for ex_code in client.exceptions._code_to_exception:
    print(ex_code)

J'espère que ça aide.

никта
la source
-5

Vous devez faire quelque chose lorsqu'il ne parvient pas à gérer le problème. À l'heure actuelle, vous renvoyez l'exception réelle. Par exemple, si ce n'est pas un problème, l'utilisateur existe déjà et que vous souhaitez l'utiliser en tant que fonction get_or_create, vous pouvez peut-être gérer le problème en renvoyant l'objet utilisateur existant.

try:
    user = iam_conn.create_user(UserName=username)
    return user
except botocore.exceptions.ClientError as e:

    #this exception could actually be other things other than exists, so you want to evaluate it further in your real code.
    if e.message.startswith(
        'enough of the exception message to identify it as the one you want')

        print('that user already exists.')
        user = iam_conn.get_user(UserName=username)
        return user

    elif e.message.some_other_condition:

         #something else
    else:
         #unhandled ClientError
         raise(e)
except SomeOtherExceptionTypeYouCareAbout as e:
    #handle it

# any unhandled exception will raise here at this point.
# if you want a general handler

except Exception as e:
    #handle it.

Cela dit, c'est peut-être un problème pour votre application, auquel cas vous souhaitez mettre le gestionnaire d'exceptions autour du code qui a appelé votre fonction utilisateur create et laisser la fonction appelante déterminer comment y faire face, par exemple, en demandant l'utilisateur à entrer un autre nom d'utilisateur, ou tout ce qui a du sens pour votre application.

tlastowka
la source
Mais le fait que l'utilisateur existe déjà n'est qu'une des nombreuses façons dont l'appel API peut échouer. Je ne vois pas de moyen de différencier ces derniers avec cette méthode.
SQDK
Démonstration du fonctionnement de la gestion des exceptions au niveau de base, car c'est là que semble être la confusion. J'ai mis un commentaire à cet effet.
tlastowka
Merci pour ça. Cela ne fait que renforcer mon soupçon que cette question est plus spécifique à Boto3 qu'à Python. Je ne connais pas les modèles courants de gestion des erreurs en python, d'où ma façon générique de poser la question
SQDK
Les objets d'exception ont des propriétés que vous pouvez évaluer davantage pour interrompre la gestion. Ceux qui sont couramment utilisés pour cela sont "message" et "args"
tlastowka
J'ai la source de l'exception ClientError ici: github.com/boto/botocore/blob/develop/botocore/… . Cela ne semble-t-il pas simplement être formaté dans une chaîne? Peut être un "problème" avec la façon dont boto3 gère ce type d'erreurs. Peut-être que les développeurs supposent qu'il n'y a que 2 scénarios possibles (que l'utilisateur existe déjà ou non), ce qui justifie de lever une exception avec uniquement une chaîne si cela ne fonctionne pas.
SQDK