From 6e47b3256edd7627e0e934d7a3199fef52ae8736 Mon Sep 17 00:00:00 2001 From: Nils Lindemann Date: Sat, 30 Mar 2024 21:28:29 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Add=20German=20translation=20for?= =?UTF-8?q?=20`docs/de/docs/tutorial/handling-errors.md`=20(#10379)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/de/docs/tutorial/handling-errors.md | 259 +++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 docs/de/docs/tutorial/handling-errors.md diff --git a/docs/de/docs/tutorial/handling-errors.md b/docs/de/docs/tutorial/handling-errors.md new file mode 100644 index 000000000..af658b971 --- /dev/null +++ b/docs/de/docs/tutorial/handling-errors.md @@ -0,0 +1,259 @@ +# Fehlerbehandlung + +Es gibt viele Situationen, in denen Sie einem Client, der Ihre API benutzt, einen Fehler zurückgeben müssen. + +Dieser Client könnte ein Browser mit einem Frontend, Code von jemand anderem, ein IoT-Gerät, usw., sein. + +Sie müssten beispielsweise einem Client sagen: + +* Dass er nicht die notwendigen Berechtigungen hat, eine Aktion auszuführen. +* Dass er zu einer Ressource keinen Zugriff hat. +* Dass die Ressource, auf die er zugreifen möchte, nicht existiert. +* usw. + +In diesen Fällen geben Sie normalerweise einen **HTTP-Statuscode** im Bereich **400** (400 bis 499) zurück. + +Das ist vergleichbar mit den HTTP-Statuscodes im Bereich 200 (von 200 bis 299). Diese „200“er Statuscodes bedeuten, dass der Request in einem bestimmten Aspekt ein „Success“ („Erfolg“) war. + +Die Statuscodes im 400er-Bereich bedeuten hingegen, dass es einen Fehler gab. + +Erinnern Sie sich an all diese **404 Not Found** Fehler (und Witze)? + +## `HTTPException` verwenden + +Um HTTP-Responses mit Fehlern zum Client zurückzugeben, verwenden Sie `HTTPException`. + +### `HTTPException` importieren + +```Python hl_lines="1" +{!../../../docs_src/handling_errors/tutorial001.py!} +``` + +### Eine `HTTPException` in Ihrem Code auslösen + +`HTTPException` ist eine normale Python-Exception mit einigen zusätzlichen Daten, die für APIs relevant sind. + +Weil es eine Python-Exception ist, geben Sie sie nicht zurück, (`return`), sondern Sie lösen sie aus (`raise`). + +Das bedeutet auch, wenn Sie in einer Hilfsfunktion sind, die Sie von ihrer *Pfadoperation-Funktion* aus aufrufen, und Sie lösen eine `HTTPException` von innerhalb dieser Hilfsfunktion aus, dann wird der Rest der *Pfadoperation-Funktion* nicht ausgeführt, sondern der Request wird sofort abgebrochen und der HTTP-Error der `HTTP-Exception` wird zum Client gesendet. + +Der Vorteil, eine Exception auszulösen (`raise`), statt sie zurückzugeben (`return`) wird im Abschnitt über Abhängigkeiten und Sicherheit klarer werden. + +Im folgenden Beispiel lösen wir, wenn der Client eine ID anfragt, die nicht existiert, eine Exception mit dem Statuscode `404` aus. + +```Python hl_lines="11" +{!../../../docs_src/handling_errors/tutorial001.py!} +``` + +### Die resultierende Response + +Wenn der Client `http://example.com/items/foo` anfragt (ein `item_id` `"foo"`), erhält dieser Client einen HTTP-Statuscode 200 und folgende JSON-Response: + +```JSON +{ + "item": "The Foo Wrestlers" +} +``` + +Aber wenn der Client `http://example.com/items/bar` anfragt (ein nicht-existierendes `item_id` `"bar"`), erhält er einen HTTP-Statuscode 404 (der „Not Found“-Fehler), und eine JSON-Response wie folgt: + +```JSON +{ + "detail": "Item not found" +} +``` + +!!! tip "Tipp" + Wenn Sie eine `HTTPException` auslösen, können Sie dem Parameter `detail` jeden Wert übergeben, der nach JSON konvertiert werden kann, nicht nur `str`. + + Zum Beispiel ein `dict`, eine `list`, usw. + + Das wird automatisch von **FastAPI** gehandhabt und der Wert nach JSON konvertiert. + +## Benutzerdefinierte Header hinzufügen + +Es gibt Situationen, da ist es nützlich, dem HTTP-Error benutzerdefinierte Header hinzufügen zu können, etwa in einigen Sicherheitsszenarien. + +Sie müssen das wahrscheinlich nicht direkt in ihrem Code verwenden. + +Aber falls es in einem fortgeschrittenen Szenario notwendig ist, können Sie benutzerdefinierte Header wie folgt hinzufügen: + +```Python hl_lines="14" +{!../../../docs_src/handling_errors/tutorial002.py!} +``` + +## Benutzerdefinierte Exceptionhandler definieren + +Sie können benutzerdefinierte Exceptionhandler hinzufügen, mithilfe derselben Werkzeuge für Exceptions von Starlette. + +Nehmen wir an, Sie haben eine benutzerdefinierte Exception `UnicornException`, die Sie (oder eine Bibliothek, die Sie verwenden) `raise`n könnten. + +Und Sie möchten diese Exception global mit FastAPI handhaben. + +Sie könnten einen benutzerdefinierten Exceptionhandler mittels `@app.exception_handler()` hinzufügen: + +```Python hl_lines="5-7 13-18 24" +{!../../../docs_src/handling_errors/tutorial003.py!} +``` + +Wenn Sie nun `/unicorns/yolo` anfragen, `raise`d die *Pfadoperation* eine `UnicornException`. + +Aber diese wird von `unicorn_exception_handler` gehandhabt. + +Sie erhalten also einen sauberen Error mit einem Statuscode `418` und dem JSON-Inhalt: + +```JSON +{"message": "Oops! yolo did something. There goes a rainbow..."} +``` + +!!! note "Technische Details" + Sie können auch `from starlette.requests import Request` und `from starlette.responses import JSONResponse` verwenden. + + **FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren Responses kommen aber direkt von Starlette. Das Gleiche gilt für `Request`. + +## Die Default-Exceptionhandler überschreiben + +**FastAPI** hat einige Default-Exceptionhandler. + +Diese Handler kümmern sich darum, Default-JSON-Responses zurückzugeben, wenn Sie eine `HTTPException` `raise`n, und wenn der Request ungültige Daten enthält. + +Sie können diese Exceptionhandler mit ihren eigenen überschreiben. + +### Requestvalidierung-Exceptions überschreiben + +Wenn ein Request ungültige Daten enthält, löst **FastAPI** intern einen `RequestValidationError` aus. + +Und bietet auch einen Default-Exceptionhandler dafür. + +Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und verwenden Sie ihn in `@app.exception_handler(RequestValidationError)`, um Ihren Exceptionhandler zu dekorieren. + +Der Exceptionhandler wird einen `Request` und die Exception entgegennehmen. + +```Python hl_lines="2 14-16" +{!../../../docs_src/handling_errors/tutorial004.py!} +``` + +Wenn Sie nun `/items/foo` besuchen, erhalten Sie statt des Default-JSON-Errors: + +```JSON +{ + "detail": [ + { + "loc": [ + "path", + "item_id" + ], + "msg": "value is not a valid integer", + "type": "type_error.integer" + } + ] +} +``` + +eine Textversion: + +``` +1 validation error +path -> item_id + value is not a valid integer (type=type_error.integer) +``` + +#### `RequestValidationError` vs. `ValidationError` + +!!! warning "Achtung" + Das folgende sind technische Details, die Sie überspringen können, wenn sie für Sie nicht wichtig sind. + +`RequestValidationError` ist eine Unterklasse von Pydantics `ValidationError`. + +**FastAPI** verwendet diesen, sodass Sie, wenn Sie ein Pydantic-Modell für `response_model` verwenden, und ihre Daten fehlerhaft sind, einen Fehler in ihrem Log sehen. + +Aber der Client/Benutzer sieht ihn nicht. Stattdessen erhält der Client einen „Internal Server Error“ mit einem HTTP-Statuscode `500`. + +Das ist, wie es sein sollte, denn wenn Sie einen Pydantic-`ValidationError` in Ihrer *Response* oder irgendwo sonst in ihrem Code haben (es sei denn, im *Request* des Clients), ist das tatsächlich ein Bug in ihrem Code. + +Und während Sie den Fehler beheben, sollten ihre Clients/Benutzer keinen Zugriff auf interne Informationen über den Fehler haben, da das eine Sicherheitslücke aufdecken könnte. + +### den `HTTPException`-Handler überschreiben + +Genauso können Sie den `HTTPException`-Handler überschreiben. + +Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen: + +```Python hl_lines="3-4 9-11 22" +{!../../../docs_src/handling_errors/tutorial004.py!} +``` + +!!! note "Technische Details" + Sie können auch `from starlette.responses import PlainTextResponse` verwenden. + + **FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren Responses kommen aber direkt von Starlette. + +### Den `RequestValidationError`-Body verwenden + +Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen Daten. + +Sie könnten diesen verwenden, während Sie Ihre Anwendung entwickeln, um den Body zu loggen und zu debuggen, ihn zum Benutzer zurückzugeben, usw. + +```Python hl_lines="14" +{!../../../docs_src/handling_errors/tutorial005.py!} +``` + +Jetzt versuchen Sie, einen ungültigen Artikel zu senden: + +```JSON +{ + "title": "towel", + "size": "XL" +} +``` + +Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungültig sind, und welche den empfangenen Body enthält. + +```JSON hl_lines="12-15" +{ + "detail": [ + { + "loc": [ + "body", + "size" + ], + "msg": "value is not a valid integer", + "type": "type_error.integer" + } + ], + "body": { + "title": "towel", + "size": "XL" + } +} +``` + +#### FastAPIs `HTTPException` vs. Starlettes `HTTPException` + +**FastAPI** hat seine eigene `HTTPException`. + +Und **FastAPI**s `HTTPException`-Fehlerklasse erbt von Starlettes `HTTPException`-Fehlerklasse. + +Der einzige Unterschied besteht darin, dass **FastAPIs** `HTTPException` alles für das Feld `detail` akzeptiert, was nach JSON konvertiert werden kann, während Starlettes `HTTPException` nur Strings zulässt. + +Sie können also weiterhin **FastAPI**s `HTTPException` wie üblich in Ihrem Code auslösen. + +Aber wenn Sie einen Exceptionhandler registrieren, registrieren Sie ihn für Starlettes `HTTPException`. + +Auf diese Weise wird Ihr Handler, wenn irgendein Teil von Starlettes internem Code, oder eine Starlette-Erweiterung, oder -Plugin eine Starlette-`HTTPException` auslöst, in der Lage sein, diese zu fangen und zu handhaben. + +Damit wir in diesem Beispiel beide `HTTPException`s im selben Code haben können, benennen wir Starlettes Exception um zu `StarletteHTTPException`: + +```Python +from starlette.exceptions import HTTPException as StarletteHTTPException +``` + +### **FastAPI**s Exceptionhandler wiederverwenden + +Wenn Sie die Exception zusammen mit denselben Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler von `fastapi.Exception_handlers` importieren und wiederverwenden: + +```Python hl_lines="2-5 15 21" +{!../../../docs_src/handling_errors/tutorial006.py!} +``` + +In diesem Beispiel `print`en Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht, aber Sie sehen, worauf wir hinauswollen. Sie können mit der Exception etwas machen und dann einfach die Default-Exceptionhandler wiederverwenden.