How to Handle Errors in boto3 | AWS SDK for Python

This article summarizes how to handle errors in boto3, AWS SDK for Python.

Introduction

I encountered some challenges when trying to catch errors in boto3.

For example, running the following code results in a BucketAlreadyExists error because the S3 bucket named examplebucket already exists:

import boto3

client = boto3.client('s3')
client.create_bucket(
    Bucket='examplebucket',
    CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
)
botocore.errorfactory.BucketAlreadyExists: An error occurred (BucketAlreadyExists) when calling the CreateBucket operation: The requested bucket name is not available.
The bucket namespace is shared by all users of the system. Please select a different name and try again.

So, how can we catch this error?

If we naively try to catch botocore.errorfactory.BucketAlreadyExists as indicated in the error message, it won’t work:

import boto3
import botocore

client = boto3.client('s3')
try:
    client.create_bucket(
        Bucket='examplebucket',
        CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
    )
except botocore.errorfactory.BucketAlreadyExists as e:
    print(e)
AttributeError: module 'botocore.errorfactory' has no attribute 'BucketAlreadyExists'

In this article, I will explore how to properly handle boto3 errors in such cases.

Note: This article was translated from my original post.

Handling Errors in boto3

There are two main ways to handle errors in boto3:

  • client.exceptions
  • botocore.exceptions

Using client.exceptions

client.exceptions allows for straightforward exception handling. You can catch errors using client.exceptions.<ErrorName> from the declared boto3 client.

import boto3

client = boto3.client('s3')
try:
    client.create_bucket(
        Bucket='examplebucket',
        CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
    )
except client.exceptions.BucketAlreadyExists as e:
    print(e.response['Error'])

If you are using a boto3 resource instead of a client, you can catch exceptions using resource.meta.client.exceptions.<ErrorName>.

import boto3

resource = boto3.resource('s3')
try:
    resource.create_bucket(
        Bucket='examplebucket',
        CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
    )
except resource.meta.client.exceptions.BucketAlreadyExists as e:
    print(e.response['Error'])

However, note that not all errors can be caught using this method. The supported exceptions for each API are listed in the boto3 documentation like this.

For more comprehensive error handling, you can use botocore.exceptions.

Using botocore.exceptions

Using botocore.exceptions results in slightly more verbose code, but it allows handling all exceptions.

import botocore
import boto3

client = boto3.client('s3')
try:
    client.create_bucket(
        Bucket='examplebucket',
        CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
    )
except botocore.exceptions.ClientError as e:
    if e.response['Error']['Code'] == 'BucketAlreadyExists':
        print(e.response['Error'])
    else:
        raise e

Here, we catch the error with botocore.exceptions.ClientError and then check response['Error']['Code'] to determine the appropriate action.

Since this method requires more lines of code, it’s preferable to use client.exceptions. However, botocore.exceptions is a reliable alternative when necessary.

Example Code

Here are some examples of exception handling in boto3. Errors like xxxAlreadyExists and NoSuchEntity are commonly encountered, so we will focus on handling these.

Handling BucketAlreadyExists error in S3 create_bucket

import boto3

client = boto3.client('s3')
try:
    client.create_bucket(
        Bucket='examplebucket',
        CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-1'},
    )
except client.exceptions.BucketAlreadyExists as e:
    print(f'S3 bucket already exists: {e.response["Error"]["BucketName"]}')

Handling NoSuchKey error in S3 get_object

import boto3

client = boto3.client('s3')
try:
    client.get_object(
        Bucket='target-bucket-001',
        Key='no-such/object-key',
    )
except client.exceptions.NoSuchKey as e:
    print(f'No such key: {e.response["Error"]["Key"]}')

Handling NoSuchEntityException error in IAM get_role

import boto3

client = boto3.client('iam')
try:
    client.get_role(
        RoleName='NoSuchRoleName'
    )
except client.exceptions.NoSuchEntityException as e:
    print(e.response['Error']['Message'])

Handling AlreadyExistsException error in Glue create_database

import boto3

client = boto3.client('glue')
try:
    client.create_database(
        DatabaseInput={
            'Name': 'test_db'
        }
    )
except client.exceptions.AlreadyExistsException as e:
    print(e.response['Error']['Message'])

Conclusion

This article summarized how to handle errors in boto3.

You can write more robust and debuggable code by implementing proper error handling.

[Related Articles]

en.bioerrorlog.work

References