<p>我正试图找出如何正确处理boto3的错误。<br />
我正在尝试创建IAM用户<br />
def create_user(username, iam_conn):<br />
try:<br />
user = iam_conn.create_user(UserName=username)<br />
return user<br />
except Exception as e:<br />
return e<br />
当调用create_user成功时,我会得到一个简洁的对象,其中包含API调用的http状态代码和新创建的用户的数据。</p>
<p>例子:<br />
{‘ResponseMetadata’:<br />
{‘HTTPStatusCode’: 200,<br />
‘RequestId’: ‘omitted’<br />
},<br />
u’User’: {u’Arn’: ‘arn:aws:iam::omitted:user/omitted’,<br />
u’CreateDate’: datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()),<br />
u’Path’: ‘/’,<br />
u’UserId’: ‘omitted’,<br />
u’UserName’: ‘omitted’<br />
}<br />
}<br />
这很有效。 但是当这失败时(比如如果用户已经存在),我只会得到一个botocore类型的对象。例外情况如果客户端错误,只有文本告诉我出了什么问题。<br />
示例:客户端错误(‘调用 CreateUser 操作时发生错误(EntityAlreadyExists):名称省略的用户已经存在。’,)<br />
这 (AFAIK) 使错误处理变得非常困难,因为我不能只打开生成的 http 状态代码(根据 IAM 的 Amazon API 文档,用户的 409 已经存在)。 这让我觉得我一定是在以错误的方式做某事。 最佳方式是 boto3 从不抛出异常,但 juts 始终返回一个反映 API 调用方式的对象。<br />
有谁能在这个问题上给我启发或给我指出正确的方向吗?</p>
<p>使用异常中包含的响应。 下面是一个例子:<br />
导入 boto3<br />
从 botocore.exceptions 导入 ClientError</p>
<p>尝试:<br />
iam = boto3.client(‘iam’)<br />
user = iam.create_user(UserName=‘fred’)<br />
print(“Created user: %s” % user)<br />
except ClientError as e:<br />
if e.response[‘Error’][‘Code’] == ‘EntityAlreadyExists’:<br />
print(“User already exists”)<br />
else:<br />
print(“Unexpected error: %s” % e)<br />
异常中的响应dict将包含以下内容:<br />
• [‘Error’][‘Code’] e.g. ‘EntityAlreadyExists’ or ‘ValidationError’<br />
• [‘ResponseMetadata’][‘HTTPStatusCode’] e.g. 400<br />
• [‘ResponseMetadata’][‘RequestId’] e.g. ‘d2b06652-88d7-11e5-99d0-812348583a35’<br />
• [‘Error’][‘Message’] e.g. “An error occurred (EntityAlreadyExists) …”<br />
• [‘Error’][‘Type’] e.g. ‘Sender’<br />
有关更多信息,请参阅:<br />
• <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html" target="_blank">boto3 error handling</a><br />
• <a href="https://botocore.amazonaws.com/v1/documentation/api/latest/client_upgrades.html#error-handling" target="_blank">botocore error handling</a></p>
<p>[更新:2018-03-07]</p>
<p>AWS Python SDK 已经开始在<a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html" target="_blank">客户端</a>(虽然不是在<a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/migration.html#resource-objects" target="_blank">资源</a>上)公开您可以明确捕获的服务异常,因此现在可以像这样编写代码:<br />
导入 botocore<br />
导入 boto3<br />
尝试:<br />
iam = boto3.client(‘iam’)<br />
user = iam.create_user(UserName=‘fred’)<br />
print(“Created user: %s” % user)<br />
except iam.exceptions.EntityAlreadyExistsException:<br />
print(“User already exists”)<br />
except botocore.exceptions.ParamValidationError as e:<br />
print(“Parameter validation error: %s” % e)<br />
except botocore.exceptions.ClientError as e:<br />
print(“Unexpected error: %s” % e)<br />
不幸的是,目前没有关于这些错误/异常的文档,但您可以获得如下核心错误列表:<br />
导入 botocore<br />
导入 boto3<br />
[e for e in dir(botocore.exceptions) if e.endswith(‘Error’)]<br />
请注意,您必须同时导入 botocore 和 boto3。 如果您只导入 botocore,那么您会发现 botocore 没有名为 exceptions 的属性。 这是因为异常是由 boto3 动态填充到 botocore 中的。<br />
您可以获得以下特定于服务的异常列表(根据需要使用相关服务替换iam):<br />
import boto3<br />
iam = boto3.client(‘iam’)<br />
[e for e in dir(iam.exceptions) if e.endswith(‘Exception’)]<br />
[更新:2021-09-07]<br />
除了前面提到的客户端异常方法之外,还有一个名为 <a href="https://github.com/benkehoe/aws-error-utils" target="_blank">aws-error-utils</a> 的第三方帮助包。<br />
<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege" target="_blank">Granting Least Privilege</a> 看起来像这样:<br />
{<br />
“Version”: “2012-10-17”,<br />
“Statement”: [<br />
{<br />
“Effect”: “Allow”,<br />
“Action”: [<br />
“s3:ListBucket”<br />
],<br />
“Resource”: [<br />
“arn:aws:s3:::bucketname”<br />
]<br />
},<br />
{<br />
“Effect”: “Allow”,<br />
“Action”: [<br />
“s3:GetObject”<br />
],<br />
“Resource”: [<br />
“arn:aws:s3:::bucketname/*”<br />
]<br />
}<br />
]<br />
}</p>