正确捕获boto3错误

Dav*_*han 15 django exception amazon-web-services boto3

我正在开发一个django应用程序,它与几个Amazon Web Services进行通信.

到目前为止,我无法处理和捕获boto3客户端抛出的异常.我正在做的事似乎不必要地单调乏味:

例:

client = boto3.client('sns')
client.create_platform_endpoint(PlatformApplicationArn=SNS_APP_ARN, Token=token)
Run Code Online (Sandbox Code Playgroud)

这可能会抛出一个botocore.errorfactory.InvalidParameterExceptionif例如令牌是坏的.

client.get_endpoint_attributes(EndpointArn=endpoint_arn)
Run Code Online (Sandbox Code Playgroud)

可能会抛出一个botocore.errorfactory.NotFoundException.

首先,我无法在代码中的任何地方找到这些错误,因此它们可能在某处生成.底线:我不能像往常一样导入它并抓住它.

第二,我发现了一个办法赶上错误在这里使用:

try:
    # boto3 stuff
except botocore.exceptions.ClientError as e:
    if e.response['Error']['Code'] == 'NotFound':
        # handle exception
    else:
        raise e
Run Code Online (Sandbox Code Playgroud)

但我必须删除Exception错误名称的一部分.似乎非常随机,我不知道如果我想抓住那个,我是否会删除Errorin botocore.exceptions.ParamValidationError.所以很难概括.

另一种捕获错误的方法是使用我得到的boto3客户端对象:

try:
    # boto3 stuff
except client.exceptions.NotFoundException as e:
    # handle exception
Run Code Online (Sandbox Code Playgroud)

这似乎是迄今为止最干净的方式.但我并不总是手头有boto3客户端对象,我想抓住错误.此外,我仍然只是在尝试,所以它主要是猜测工作.

有谁知道应该如何处理boto3错误?

或者可以指出我提到一些连贯的文档,提到上面的错误?谢谢

ben*_*hor 6

您已经很好地概括了情况。旧的boto使用简单的硬编码方法来支持AWS API。boto3,似乎是在尝试减少使Python客户端与各种api上不断发展的功能保持同步的开销,但对于异常的要求却更加松懈,因此,您上面概述的ClientError方法曾经是规范方法。

在2017年,他们引入了您强调的第二种机制:客户端上可用的``建模''异常。

我对SNS并不熟悉,但是根据我在其他AWS产品上的经验,ClientError的命名与HTTP api相匹配,而api的记载往往很好。所以我将从这里开始:https : //docs.aws.amazon.com/sns/latest/api/Welcome.html

看起来新样式的异常是从botocore模块中的服务定义文件生成的。我找不到有关它的任何文档,但是请浏览https://github.com/boto/botocore/tree/master/botocore/data中的AWS服务模型。

另外,很高兴知道,如果您不(与OP的代码相反)直接与低级客户端打交道,而是使用高级AWS ServiceResource对象,那么仍然可以轻松使用低级客户端,my_service_resource.meta.client因此您可以处理如下异常:

try:
    my_service_resource.do_stuff()
except my_service_resource.meta.client.exceptions.NotFoundException as e:
    # handle exception
Run Code Online (Sandbox Code Playgroud)

  • @AaronMcMillin boto 公开了两种客户端。一个是低级 Client 对象,因为 OP 正在使用并且您也在使用。您可以通过调用 `boto3.client('s3')` 获得其中之一(让我们以 s3 为例)。还有一个更高级别的“服务资源”对象,在一般意义上将其称为客户端也是合理的。你会得到一个这样的:`s3 = boto3.resource('s3')`。Boto 文档倾向于将用户指向简单用例的资源对象,所以我认为值得指出差异。 (2认同)

小智 6

使用 Boto3 例外:https ://www.programcreek.com/python/example/97944/boto3.exceptions

client = boto3.client('logs')
try:
   client.create_log_group(logGroupName=LOG_GROUP)
except client.exceptions.ResourceAlreadyExistsException:
   pass
Run Code Online (Sandbox Code Playgroud)