Ich versuche herauszufinden, wie man mit boto3 richtig Fehler behandelt.
Ich versuche, einen IAM-Benutzer zu erstellen:
def create_user(username, iam_conn):
try:
user = iam_conn.create_user(UserName=username)
return user
except Exception as e:
return e
Wenn der Aufruf von create_user erfolgreich ist, erhalte ich ein ordentliches Objekt, das den http-Statuscode des API-Aufrufs und die Daten des neu erstellten Benutzers enthält.
Beispiel:
{'ResponseMetadata':
{'HTTPStatusCode': 200,
'RequestId': 'omitted'
},
u'User': {u'Arn': 'arn:aws:iam::omitted:user/omitted',
u'CreateDate': datetime.datetime(2015, 10, 11, 17, 13, 5, 882000, tzinfo=tzutc()),
u'Path': '/',
u'UserId': 'omitted',
u'UserName': 'omitted'
}
}
Das funktioniert super. Wenn dies jedoch fehlschlägt (z. B. wenn der Benutzer bereits vorhanden ist), erhalte ich nur ein Objekt vom Typ botocore.exceptions.ClientError mit nur Text, um mir mitzuteilen, was schief gelaufen ist.
Beispiel: ClientError ('Beim Aufrufen der CreateUser-Operation ist ein Fehler aufgetreten (EntityAlreadyExists): Benutzer mit weggelassenem Namen ist bereits vorhanden.',)
Dies (AFAIK) macht die Fehlerbehandlung sehr schwierig, da ich den resultierenden http-Statuscode nicht einfach einschalten kann (409 für Benutzer existiert bereits gemäß den AWS API-Dokumenten für IAM). Das lässt mich denken, dass ich etwas falsch machen muss. Der optimale Weg wäre, dass boto3 niemals Ausnahmen auslöst, aber juts gibt immer ein Objekt zurück, das den Verlauf des API-Aufrufs widerspiegelt.
Kann mich jemand über dieses Thema aufklären oder in die richtige Richtung weisen?
Antworten:
Verwenden Sie die in der Ausnahme enthaltene Antwort. Hier ist ein Beispiel:
Das Antwortdiktat in der Ausnahme enthält Folgendes:
['Error']['Code']
zB 'EntityAlreadyExists' oder 'ValidationError'['ResponseMetadata']['HTTPStatusCode']
zB 400['ResponseMetadata']['RequestId']
zB 'd2b06652-88d7-11e5-99d0-812348583a35'['Error']['Message']
zB "Ein Fehler ist aufgetreten (EntityAlreadyExists) ..."['Error']['Type']
zB 'Absender'Weitere Informationen finden Sie unter Behandlung von Botocore-Fehlern .
[Aktualisiert: 2018-03-07]
Das AWS Python SDK hat damit begonnen, Dienstausnahmen auf Clients (jedoch nicht auf Ressourcen) bereitzustellen ) , die Sie explizit abfangen können. Daher ist es jetzt möglich, diesen Code wie folgt zu schreiben:
Leider gibt es derzeit keine Dokumentation für diese Ausnahmen.
quelle
200
für Ihre Prüfung verwenden, da der Rückkehrcode ein anderer2xx
HTTP-Statuscode sein kann (z. B.204
beim Löschen eines Tresors oder Archivs,201
beim Erstellen usw.). Bestenfalls sollte man nach einem Nicht-4xx-Code suchen (z. B.statusCode < 400
), aber das ist wirklich spröde, und ich würde es sowieso nicht empfehlen: Am besten verlassen Sie sich daraufboto
, Ausnahmen auf Ihren Code zu werfen.Ich fand es sehr nützlich, da die Ausnahmen nicht dokumentiert sind, alle Ausnahmen auf dem Bildschirm für dieses Paket aufzulisten. Hier ist der Code, mit dem ich es gemacht habe:
Was in ... endet:
quelle
Nur eine Aktualisierung des Problems "Keine Ausnahmen bei Ressourcen", auf das @jarmod hinweist (bitte zögern Sie nicht, Ihre Antwort zu aktualisieren, wenn dies unten zutreffend erscheint).
Ich habe den folgenden Code getestet und er läuft einwandfrei. Es verwendet 'Ressourcen', um Dinge zu erledigen , fängt aber das ab
client.exceptions
- obwohl es etwas falsch 'aussieht' ... es testet gut, die Ausnahmeklassen werden angezeigt und stimmen überein, wenn die Verwendung des Debuggers zur Ausnahmezeit untersucht wird ...Es ist möglicherweise nicht für alle Ressourcen und Clients anwendbar, funktioniert jedoch für Datenordner (auch bekannt als s3-Buckets).
Hoffe das hilft...
quelle
s3.meta.client.exceptions.NoSuchBucket
s3
ist die Serviceressource, zs3 = boto3.resource('s3')
. Funktioniert auch für die eigentlichen Ressourcen wie Eimer:boto3.resource('s3').Bucket('bucket-name').meta.client.exceptions. ...
Wie bereits erwähnt, können Sie bestimmte Fehler mit dem Service-Client (
service_client.exceptions.<ExceptionClass>
) oder der Ressource (service_resource.meta.client.exceptions.<ExceptionClass>
) abfangen. Diese sind jedoch nicht gut dokumentiert (auch welche Ausnahmen zu welchen Clients gehören). So erhalten Sie die vollständige Zuordnung zum Zeitpunkt des Schreibens (Januar 2020) in der Region EU (Irland) (eu-west-1
):Hier ist eine Teilmenge des ziemlich großen Dokuments:
quelle
Oder ein Vergleich des Klassennamens zB
Da sie dynamisch erstellt werden, können Sie die Klasse niemals importieren und mit echtem Python abfangen.
quelle
except Exception as e
und dann if-Anweisungen haben, um die spezifische Ausnahme zu bestimmen? Wie unterscheidet sich das von / besser als das Abfangen bestimmter Ausnahmen? Es sind mehr Zeilen, und Sie müssten die Bibliothek importieren, um den Klassennamen trotzdem zu erhalten. Es sei denn, Sie möchten den Ausnahmenamen fest codieren. Alles in allem scheint es ein schlechter Weg zu sein.Wenn Sie die sign_up-API (AWS Cognito) mit Python3 aufrufen, können Sie den folgenden Code verwenden.
error.response ['Error'] ['Code'] ist InvalidPasswordException, UsernameExistsException usw. In der Hauptfunktion oder wo Sie die Funktion aufrufen, können Sie die Logik schreiben, um dem Benutzer eine aussagekräftige Nachricht zu liefern.
Ein Beispiel für die Antwort (error.response):
Weitere Informationen: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.sign_up
quelle
Für den Fall, dass Sie sich mit dem wohl unfreundlichen
logs
Client ( CloudWatch Logsput-log-events
) befassen müssen, musste ich Folgendes tun, um die Ausnahmen für Boto3-Clients ordnungsgemäß zu erfassen:Dies funktioniert sowohl beim ersten Versuch (mit leerem LogStream) als auch bei den nachfolgenden.
quelle
Nach dem Update von @ armod über Ausnahmen, die direkt zu
client
Objekten hinzugefügt werden. Ich werde zeigen, wie Sie alle für Ihre Clientklasse definierten Ausnahmen sehen können.Ausnahmen werden dynamisch generiert, wenn Sie Ihren Client mit
session.create_client()
oder erstellenboto3.client()
. Intern ruft es method aufbotocore.errorfactory.ClientExceptionsFactory._create_client_exceptions()
und füllt dasclient.exceptions
Feld mit konstruierten Ausnahmeklassen.Alle Klassennamen sind im
client.exceptions._code_to_exception
Wörterbuch verfügbar , sodass Sie alle Typen mit folgendem Snippet auflisten können:Ich hoffe es hilft.
quelle
Sie müssen etwas tun, wenn das Problem nicht behoben werden kann. Im Moment geben Sie die eigentliche Ausnahme zurück. Wenn es beispielsweise kein Problem ist, dass der Benutzer bereits vorhanden ist und Sie ihn als Funktion get_or_create verwenden möchten, können Sie das Problem möglicherweise beheben, indem Sie das vorhandene Benutzerobjekt zurückgeben.
Das heißt, vielleicht ist es ein Problem für Ihre App. In diesem Fall möchten Sie den Ausnahmehandler um den Code setzen, der Ihre Funktion zum Erstellen eines Benutzers aufgerufen hat, und die aufrufende Funktion bestimmen lassen, wie sie damit umgehen soll, indem Sie beispielsweise fragen Der Benutzer muss einen anderen Benutzernamen eingeben oder was auch immer für Ihre Anwendung sinnvoll ist.
quelle