Whenever I get an exception in boto which I want to catch, I copy and paste the exception code into the except block, and it normally fails because python doesn't know which exception I'm trying to catch.
Run the following code:
````
import botocore
import boto3
client = boto3.client('s3')
b = 'somebucketnamewhichdoesntexist'
response = client.get_bucket_location(
Bucket=b
)
````
Because that bucket doesn't exist, boto raises a botocore.errorfactory.NoSuchBucket exception.
So copy and paste botocore.errorfactory.NoSuchBucket into an except block.
````
import botocore
import boto3
client = boto3.client('s3')
b = 'somebucketnamewhichdoesntexist'
try:
response = client.get_bucket_location(
Bucket=b
)
except botocore.errorfactory.NoSuchBucket as e:
print('bucket %s doesnt exist')
````
Run this new code
except block catches the exceptionbucket somebucketnamewhichdoesntexist doesnt existThe interpreter doesn't know what botocore.errorfactory.NoSuchBucket is
Traceback (most recent call last):
File "botofail.py", line 13, in
except botocore.errorfactory.NoSuchBucket as e:
AttributeError: 'module' object has no attribute 'NoSuchBucket'
Modeled exceptions needs to be accessed through the client.
So rather than having botocore.errorfactory.NoSuchBucket you need client.exceptions.NoSuchBucket. I agree that this is confusing and the current documentation is insufficient.
More information on this can be found at this pr: https://github.com/boto/botocore/pull/1113 and this issue: https://github.com/boto/boto3/issues/167
using build to create a webmasters resource, I'm told the client has no 'exceptions' -- has this changed since July?
I think it needs to be a 'client' as a 'resource' doesn't have 'exceptions.
I'm trying to capture a 'botocore.errorfactory.AlreadyExistsException' but this is raised by a 'resource', documentation here is very lacking...
I have code that may use local storage or s3 - when using local storage I don't create an s3 client, so my try/except code fails since it tries to get the exception from None.
It would be nice to be able to get the exceptions from a class rather than from an object.
To access the client exceptions from a resource, it might be possible using:
>>> type(s3)
<class 'boto3.resources.factory.s3.ServiceResource'>
>>> s3.meta.client.exceptions
<botocore.errorfactory.S3Exceptions object at 0x7f2c97eb8128>
>>> s3.meta.client.exceptions.NoSuchBucket
<class 'botocore.errorfactory.NoSuchBucket'>
>>> s3.meta.client.exceptions.NoSuchKey
<class 'botocore.errorfactory.NoSuchKey'>
But these don't actually catch a
botocore.exceptions.ClientError: An error occurred (404) when calling the HeadObject operation: Not Found
In general, the docs are confusing with regard to the preferred idioms for using a client or a resource to download an s3 file and handle exceptions gracefully.
I ran into the same issue, and what I want to do is debug why something isn't working, but none of the standard python methods for try/except seem to work (still: may 2019).
botocore should remove the factories and modify them to drop static files into botocore so there was both traceability and ease of understanding. As it is, there are quite a few really poorly contrived python structures. The factories in use here are an anti-pattern for the user.
Current code to make sense of some exceptions has to inspect the response content of the client exception, e.g.
def stat(bucket, key):
try:
client = boto3.client("s3")
return client.head_object(Bucket=bucket, Key=key)
except botocore.exceptions.ClientError as err:
status = err.response["ResponseMetadata"]["HTTPStatusCode"]
errcode = err.response["Error"]["Code"]
if status == 404:
logging.warning("Missing object, %s", errcode)
elif status == 403:
logging.error("Access denied, %s", errcode)
else:
logging.exception("Error in request, %s", errcode)
return {}
Most helpful comment
Modeled exceptions needs to be accessed through the client.
So rather than having
botocore.errorfactory.NoSuchBucketyou needclient.exceptions.NoSuchBucket. I agree that this is confusing and the current documentation is insufficient.More information on this can be found at this pr: https://github.com/boto/botocore/pull/1113 and this issue: https://github.com/boto/boto3/issues/167