【问题标题】:Properly catch boto3 Errors正确捕获 boto3 错误
【发布时间】:2017-09-12 10:46:09
【问题描述】:

我正在开发一个与多个亚马逊网络服务通信的 django 应用程序。

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

例子:

client = boto3.client('sns')
client.create_platform_endpoint(PlatformApplicationArn=SNS_APP_ARN, Token=token)

这可能会抛出botocore.errorfactory.InvalidParameterException,例如令牌坏了。

client.get_endpoint_attributes(EndpointArn=endpoint_arn)

可能会抛出botocore.errorfactory.NotFoundException

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

其次,我找到了一种捕获错误here的方法:

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

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

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

try:
    # boto3 stuff
except client.exceptions.NotFoundException as e:
    # handle exception

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

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

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

【问题讨论】:

标签: python amazon-web-services exception boto3


【解决方案1】:

你已经很好地总结了情况。旧的 boto 有一个简单的硬编码方法来支持 AWS API。 boto3,似乎是为了减少保持 Python 客户端与各种 api 上不断发展的功能同步的开销,在异常情况下更加糊涂,因此您上面概述的 ClientError 方法曾经是规范的方法。

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

我不熟悉 SNS,但根据我使用其他 AWS 产品的经验,ClientError 命名与 HTTP 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

【讨论】:

  • 谢谢,文档链接正是我所需要的!所以似乎第一个选项更好,因为它使用记录的异常名称。 NotFound 记录了异常,NotFoundException 没有记录。我想这是您提到的硬编码/保持同步问题的一部分?因为如果不是,我不明白该异常名称的来源,因为它没有出现在 API 文档中的任何地方。
  • 我决定去看看。事实证明,有一种服务发现机制正在运行,它基于以声明方式存储在 botocore 中的定义。查看github.com/boto/botocore/tree/master/botocore/data。我将更新答案以反映这一发现。
  • 我在meta下没有异常,它们直接在客户端所以my_server_resource.exceptions.NotFoundException
  • @AaronMcMillin boto 公开了两种客户端。一个是低级 Client 对象,因为 OP 正在使用并且您也在使用。您可以通过调用boto3.client('s3') 获得其中之一(让我们以s3 为例)。还有一个更高级别的“服务资源”对象,将其称为一般意义上的客户端也是合理的。你会得到一个这样的:s3 = boto3.resource('s3')。 Boto 文档倾向于将用户指向简单用例的资源对象,因此我认为值得指出其中的区别。
  • @benauthor 我们是否需要在 do_stuff 之后检查状态码以作为响应?就像if resp["ResponseMetadata"].get("HTTPStatusCode") != 200 如果我也在捕获响应resp = my_service_resource.do_stuff()
【解决方案2】:

使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2023-04-07
    • 2020-04-17
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多