¿Cómo capturar la excepción NoSuchKey de botocore?

105

Estoy tratando de escribir Python "bueno" y capturar un S3 sin tal error de clave con esto:

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"

Pero NoSuchKey no está definido y no puedo rastrearlo hasta la importación, necesito definirlo.

e.__class__es botocore.errorfactory.NoSuchKeypero from botocore.errorfactory import NoSuchKeyda un error y from botocore.errorfactory import *tampoco funciona y no quiero capturar un error genérico.

teísta
fuente

Respuestas:

127
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
fuente
51

Usando botocore 1.5, parece que el identificador del cliente expone las clases de excepción:

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
fuente
Estoy optando por este, ya que es más nuevo y menos genérico. Puede encontrar algunos comentarios en GitHub con respecto a este método: github.com/boto/boto3/issues/1262#issuecomment-329314670
Sylwester Kardziejonek
Si olvidó desplazarse como yo: si está utilizando el recurso de alto nivel ( s3 = boto3.resource("s3")), puede acceder al cliente y, por lo tanto, a la Excepción a través de s3.meta.client.exceptions.NoSuchKey. Ver stackoverflow.com/questions/38581465/…
lorey
32

En boto3, pude acceder a la excepción en el metacliente del 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")
Cachondo
fuente
Usar la metainformación es, en mi opinión, la forma más elegante
Tanja Bayer hace
24

Creo que la forma más elegante de hacer esto es en Boto3 es

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")

La documentación sobre el manejo de errores parece escasa, pero lo siguiente imprime los códigos de error para los que 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)

<botocore.errorfactory.S3Exceptions objeto en 0x105e08c50> el objeto no tiene atributo 'InvalidBucketName'. Las excepciones válidas son: BucketAlreadyExists, BucketAlreadyOwnedByYou, NoSuchBucket, NoSuchKey, NoSuchUpload, ObjectAlreadyInActiveTierError, ObjectNotInActiveTierError

JeffSolo
fuente
Por razones que pueden no estar relacionadas, cuando atrapo Excepciones de esta manera, no se propagan. (?)
Everett