我试图弄清楚如何使用boto3进行正确的错误处理。
我正在尝试创建一个IAM用户:
def create_user(username, iam_conn):
try:
user = iam_conn.create_user(UserName=username)
return user
except Exception as e:
return e
当调用create_user成功时,我得到一个整洁的对象,其中包含API调用的http状态代码和新创建用户的数据。
例子:
{'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'
}
}
这很有效。但是当这个失败时(比如如果用户已经存在),我只得到一个botocore.exceptions.ClientError类型的对象,其中只有文本告诉我哪里出错了。
例子:
ClientError('调用CreateUser操作时发生错误(EntityAlreadyExists):省略名称的用户已经存在。')
这(AFAIK)使得错误处理非常困难,因为我不能只是打开结果的http状态代码(409用户已经存在根据AWS API文档的IAM)。这让我觉得我一定是做错了什么。最优的方法是boto3永远不抛出异常,但juts总是返回一个反映API调用如何进行的对象。
有没有人能在这个问题上给我一些启发,或者给我指出正确的方向?
使用异常中包含的响应。这里有一个例子:
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)
异常中的响应字典将包含以下内容:
(“错误”)(“代码”)。'EntityAlreadyExists'或'ValidationError'
[' responsemetdata ']['HTTPStatusCode']例:400
[“ResponseMetadata”][' RequestId ']。“d2b06652 - 88 - d7 - 11 - e5 - 99 - d0 - 812348583 - a35”
(“错误”)(“信息”)。"发生错误(EntityAlreadyExists)…"
['错误']['类型']。“发送”
有关更多信息,请参阅:
Boto3错误处理
Botocore错误处理
(更新:2018-03-07)
AWS Python SDK已经开始公开客户端上的服务异常(虽然不是资源上的异常),你可以显式地捕获这些异常,所以现在可以像这样编写代码:
import botocore
import boto3
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 botocore.exceptions.ParamValidationError as e:
print("Parameter validation error: %s" % e)
except botocore.exceptions.ClientError as e:
print("Unexpected error: %s" % e)
不幸的是,目前没有关于这些错误/异常的文档,但你可以得到一个核心错误列表,如下所示:
import botocore
import boto3
[e for e in dir(botocore.exceptions) if e.endswith('Error')]
注意,必须同时导入botocore和boto3。如果你只导入botocore,你会发现botocore没有名为exceptions的属性。这是因为异常被boto3动态地填充到botocore中。
您可以获得以下特定于服务的异常列表(根据需要将iam替换为相关的服务):
import boto3
iam = boto3.client('iam')
[e for e in dir(iam.exceptions) if e.endswith('Exception')]
(更新:2021-09-07)
除了前面提到的客户端异常方法之外,还有一个名为aws-error-utils的第三方帮助包。