개요
Python으로 boto3을 사용할 때 발생하는 예외를 처리해 로그 또는 메시지를 남기거나 예외를 무시해야 하는 경우가 있다.
이 글에서는 boto3을 사용할 때 발생하는 예외를 처리하는 방법을 정리해둔다.
예외 종류
boto3를 사용할 때는 botocore 또는 AWS Service에서 예외가 발생할 수 있다.
Botocore Exception
Boto3가 의존하는 botocore 패키지 내에 정적으로 정의되는 예외이다. 클라이언트 측의 동작, 구성, 유효성 검사와 관련된 예외가 정의되어 있다.
정의된 예외는 https://github.com/boto/botocore/blob/develop/botocore/exceptions.py 에서 확인할 수 있다.
AWS Service Exception
botocore exception과 달리 AWS 서비스 예외는 광범위하고 변경될 수 있기 때문에 botocore에 정적으로 정의되어 있지 않다. 따라서 AWS Service 예외도 botocore 예외인 ClientError로 발생하며, AWS Service 에러로 인한 응답은 공통된 구조를 가진다.
Resource Client Exception
Resource를 이용하여 AWS 서비스와 상호작용하는 경우에는 resoucre 객체의 meta 속성을 통해 예외를 탐지해야 한다. 이후 에러 응답을 분석해야 한다.
예외 처리 방법
Botocore Exception
예외가 botocore 패키지에 정의되어 있으므로 botocore import가 필요하다.
try ~ except문을 사용하여 발생한 에러를 탐지하고 처리한다.
import botocore
import boto3
client = boto3.client('aws_service_name')
try:
client.some_api_call(SomeParam='some_param')
except botocore.exceptions.ClientError as error:
# Put your error handling logic here
raise error
except botocore.exceptions.ParamValidationError as error:
raise ValueError(f'The parameters you provided are incorrect: {error}'}
AWS Service Exception
AWS Service 예외는 botocore 예외인 ClientError로 발생하기 때문에, ClientError를 탐지해야 한다.
예외를 탐지한 이후에는 응답을 분석하여 오류와 관련된 정보를 확인해야 한다. AWS Service 에러로 인한 응답은 아래 예시와 같다.
{
'Error': {
'Code': 'SomeServiceException',
'Message': 'Details/context around the exception or error'
},
'ResponseMetadata': {
'RequestId': '1234567890ABCDEF',
'HostId': 'host ID data will appear here as a hash',
'HTTPStatusCode': 400,
'HTTPHeaders': {'header metadata key/values will appear here'},
'RetryAttempts': 0
}
}
즉, 응답으로 받은 Dictionary 객체를 분석하여 어떤 AWS Service 에러가 발생한 것인지 확인해야 한다.
import botocore
import boto3
client = boto3.client('sqs')
queue_url = 'SQS_QUEUE_URL'
try:
client.send_message(QueueUrl=queue_url, MessageBody=('some_message'))
except botocore.exceptions.ClientError as err:
if err.response['Error']['Code'] == 'InternalError': # Generic error
# We grab the message, request ID, and HTTP code to give to customer support
print(f'Error Message: {err.response['Error']['Message']}')
print(f'Request ID: {err.response['ResponseMetadata']['RequestId']}')
print(f'Http code: {err.response['ResponseMetadata']['HTTPStatusCode']}')
else:
raise err
Resource Client Exception
botocore에 정의되어 있는 Exception 대신 client.meta.client.exceptions에 정의된 Exceptiond을 탐지해야 한다.
import botocore
import boto3
client = boto3.resource('s3')
try:
client.create_bucket(BucketName='myTestBucket')
except client.meta.client.exceptions.BucketAlreadyExists as err:
print(f"Bucket {err.response['Error']['BucketName']} already exists!")
raise err
참고 문서
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html#error-handling