1. ホーム
  2. パイソン

[解決済み】boto3でエラーが発生した場合の対処方法について

2022-04-02 23:56:29

質問

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ステータスコード(IAMのAWS APIドキュメントによると、user already existsの場合は409)をそのまま切り替えることができないからである。これは、私が何か間違った方法を取っているに違いないと思わせます。最適な方法は、boto3が例外を投げず、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)

例外のレスポンスdictには、以下の内容が含まれます。

  • ['Error']['Code'] 例:'EntityAlreadyExists' や 'ValidationError' など。
  • ['ResponseMetadata']['HTTPStatusCode'] 例:400
  • ['ResponseMetadata']['RequestId'] e.g. 'd2b06652-88d7-11e5-99d0-812348583a35'
  • ['Error']['Message'] 例)"エラーが発生しました(EntityAlreadyExists) ..."
  • ['Error']['Type'] 例:「送信者

詳しくはこちらをご覧ください。

[更新日: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 .