Wie kann man die NoSuchKey-Ausnahme von Botocore erfassen?

94

Ich versuche, "gute" Python zu schreiben und einen S3 ohne solchen Schlüsselfehler zu erfassen:

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"

Aber NoSuchKey ist nicht definiert und ich kann es nicht auf den Import zurückführen, für den ich es definieren muss.

e.__class__ist botocore.errorfactory.NoSuchKeyaber from botocore.errorfactory import NoSuchKeygibt einen Fehler und from botocore.errorfactory import *funktioniert auch nicht und ich möchte keinen generischen Fehler erfassen.

Theist
quelle

Antworten:

109
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
quelle
49

Bei Verwendung von Botocore 1.5 sieht es so aus, als ob das Client-Handle die Ausnahmeklassen verfügbar macht:

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
quelle
Ich entscheide mich für dieses, da es neuer und auch weniger generisch ist. Sie können einige Kommentare auf GitHub zu dieser Methode finden: github.com/boto/boto3/issues/1262#issuecomment-329314670
Sylwester Kardziejonek
Wenn Sie vergessen haben, wie ich zu scrollen: Wenn Sie die übergeordnete Ressource ( s3 = boto3.resource("s3")) verwenden, können Sie über auf den Client und damit auf die Ausnahme zugreifen s3.meta.client.exceptions.NoSuchKey. Siehe stackoverflow.com/questions/38581465/…
lorey
28

In boto3 konnte ich auf die Ausnahme im Meta-Client der Ressource zugreifen.

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")
Geil
quelle
21

Ich denke, der eleganteste Weg, dies zu tun, ist in 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")

Die Dokumentation zur Fehlerbehandlung scheint spärlich zu sein, aber im Folgenden werden die Fehlercodes gedruckt, für die dies funktioniert:

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)

Das Objekt <botocore.errorfactory.S3Exceptions at 0x105e08c50> hat kein Attribut 'InvalidBucketName'. Gültige Ausnahmen sind: BucketAlreadyExists, BucketAlreadyOwnedByYou, NoSuchBucket, NoSuchKey, NoSuchUpload, ObjectAlreadyInActiveTierError, ObjectNotInActiveTierError

JeffSolo
quelle
Wenn ich Ausnahmen auf diese Weise abfange, verbreiten sie sich aus Gründen, die möglicherweise nichts miteinander zu tun haben, nicht. (?)
Everett