2019-10-14

boto3 の Waiter さんとの戯れ

こないだの仕事。AWS Certificate Manager で証明書をごにょごにょするアプリを書いた。

Python で書いたので AWS のリソースを操作するのに Boto3 というライブラリを利用した。証明書を発行したあと検証済みになるまでの待受処理がWaiterという機能で提供されていたり、非常に便利で大変お世話になっている。

ただ、一つバグらせてしまったところがあった。

Waiterさんは AWS のリソースを操作する API をラップしているだけ1なので、API がエラーを発生させた場合と待受処理がタイムアウトした場合のどちらとも、WaiterErrorを発生させる。つまり単純にキャッチするだけの例外処理では違いに気づけないのだ 😱

どのようにハンドリングするか?WaiterErrorさんの属性を調べてあげれば良い。

dirしたらlast_responseなる属性があったのでそいつを見たら、もとのエラーが何だったのかは分かる形にはなってた。

エラーの場合、WaiterError.last_response['Error']にエラー情報が格納される。Waiterさんがリトライ回数の上限に達してWaiterErrorをぶん投げてきた場合は、last_responseにはWaiterさんが内包する API の戻り値が架空されるので、それをもとにエラー処理すれば良いのがわかった。以下イメージ。

{'Error': {'Message': 'Could not find certificate arn:aws:acm:ap-northeast-1:xxxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx in account xxxxxxxxxxxx.', 'Code': 'ResourceNotFoundException'}, 'ResponseMetadata': {'RequestId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'HTTPStatusCode': 400, 'HTTPHeaders': {'x-amzn-requestid': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'content-type': 'application/x-amz-json-1.1', 'content-length': '191', 'date': 'Fri, 11 Oct 2019 03:51:10 GMT', 'connection': 'close'}, 'RetryAttempts': 0}}

👍


  1. 証明書の検証済みを待つACM.Waiter.CertificateValidatedの場合はACM.Client.describe_certificate()をラップしている。