Como capturar a exceção NoSuchKey do botocore?

97

Estou tentando escrever um python "bom" e capturar um S3 sem esse erro de chave com este:

session = botocore.session.get_session()
client = session.create_client('s3')
try:
    client.get_object(Bucket=BUCKET, Key=FILE)
except NoSuchKey as e:
    print >> sys.stderr, "no such key in bucket"

Mas NoSuchKey não está definido e não consigo rastreá-lo até a importação que preciso defini-lo.

e.__class__é, botocore.errorfactory.NoSuchKeymas from botocore.errorfactory import NoSuchKeydá um erro e from botocore.errorfactory import *também não funciona e não quero capturar um erro genérico.

teísta
fonte

Respostas:

112
from botocore.exceptions import ClientError

try:
    response = self.client.get_object(Bucket=bucket, Key=key)
    return json.loads(response["Body"].read())
except ClientError as ex:
    if ex.response['Error']['Code'] == 'NoSuchKey':
        logger.info('No object found - returning empty')
        return dict()
    else:
        raise
Jose Alban
fonte
50

Usando o botocore 1.5, parece que o identificador do cliente expõe as classes de exceção:

session = botocore.session.get_session()
client = session.create_client('s3')
try:
    client.get_object(Bucket=BUCKET, Key=FILE)
except client.exceptions.NoSuchKey as e:
    print >> sys.stderr, "no such key in bucket"
Groner
fonte
Estou optando por este, porque é mais recente e também menos genérico. Você pode encontrar alguns comentários no GitHub sobre esse método: github.com/boto/boto3/issues/1262#issuecomment-329314670
Sylwester Kardziejonek
Se você esqueceu de rolar como eu: Se você estiver usando o recurso de alto nível ( s3 = boto3.resource("s3")), você pode acessar o cliente e, portanto, a Exceção via s3.meta.client.exceptions.NoSuchKey. Consulte stackoverflow.com/questions/38581465/…
lorey
30

No boto3, consegui acessar a exceção no meta cliente do recurso.

import boto3

s3 = boto3.resource('s3')
s3_object = s3.Object(bucket_name, key)

try:
    content = s3_object.get()['Body'].read().decode('utf-8')
except s3.meta.client.exceptions.NoSuchKey:
    print("no such key in bucket")
Randy
fonte
21

Acho que a maneira mais elegante de fazer isso é no Boto3 é

session = botocore.session.get_session()
client = session.create_client('s3')

try:
    client.get_object(Bucket=BUCKET, Key=FILE)
except client.exceptions.NoSuchKey:
    print("no such key in bucket")

A documentação sobre tratamento de erros parece esparsa, mas a seguir imprime os códigos de erro para os quais isso funciona:

session = botocore.session.get_session()
client = session.create_client('s3')
try:
    try:
        client.get_object(Bucket=BUCKET, Key=FILE)
    except client.exceptions.InvalidBucketName:
        print("no such key in bucket")
except AttributeError as err:
    print(err)

Objeto <botocore.errorfactory.S3Exceptions em 0x105e08c50> objeto não tem atributo 'InvalidBucketName'. As exceções válidas são: BucketAlreadyExists, BucketAlreadyOwnedByYou, NoSuchBucket, NoSuchKey, NoSuchUpload, ObjectAlreadyInActiveTierError, ObjectNotInActiveTierError

JeffSolo
fonte
Por razões que podem não estar relacionadas, quando eu intercepto exceções dessa forma, elas não se propagam. (?)
Everett