Fehlerbehandlung: GraphQlInputException und GraphQlAuthorizationException richtig einsetzen
Fehlerbehandlung: GraphQlInputException und GraphQlAuthorizationException richtig einsetzen
~8 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026
Die vorherigen Kapitel haben bereits GraphQlNoSuchEntityException (Kapitel 15) und GraphQlAuthorizationException (Kapitel 18) eingesetzt, ohne die komplette Exception-Familie systematisch vorzustellen. Dieses Kapitel schließt Block 5 mit genau dieser Übersicht ab und ergänzt die bisher fehlende GraphQlInputException.
Warum nicht einfach eine normale Exception werfen?
Eine gewöhnliche \Exception oder \RuntimeException würde Magento zwar auch abfangen, aber als generischen, unkategorisierten Internal-Server-Error behandeln - im Produktivmodus mit der nichtssagenden Meldung "Internal server error" ohne jeden Hinweis, was schiefgelaufen ist. Die GraphQL-spezifischen Exceptions aus dem Namespace \Magento\Framework\GraphQl\Exception tragen dagegen jeweils eine eigene category, die im Response-Feld extensions.category landet - Clients können so gezielt zwischen Fehlerarten unterscheiden, statt jeden Fehler gleich zu behandeln.
Die vier wichtigsten GraphQL-Exceptions
GraphQlInputException- Kategoriegraphql-input: fachlich ungültige Eingabe, die syntaktisch gültiges GraphQL ist (z. B. eine Kapazität von-5).GraphQlAuthorizationException- Kategoriegraphql-authorization: Anfrage syntaktisch/fachlich korrekt, aber der Aufrufer darf sie nicht ausführen (Kapitel 18).GraphQlNoSuchEntityException- Kategoriegraphql-no-such-entity: referenzierte Entität existiert nicht (Kapitel 15).GraphQlAlreadyExistsException- Kategoriegraphql-already-exists: ein Erstellungsvorgang würde einen bereits vorhandenen, eindeutigen Wert duplizieren.
GraphQlInputException am Beispiel: Kapazität validieren
AddEventToFavorites braucht dafür kein Beispiel - es hat keine validierungspflichtigen Eingabefelder außer der bereits geprüften ID. Realistisch wird die fehlende Validierung dagegen bei einer künftigen updateEventCapacity-artigen Mutation. Fiktives, aber realistisches Beispiel:
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
$capacity = (int) ($args['input']['capacity'] ?? 0);
if ($capacity < 0) {
throw new GraphQlInputException(
__('Capacity must not be negative, got "%1".', $capacity)
);
}Die Faustregel zur Abgrenzung von GraphQlInputException gegenüber GraphQlAuthorizationException: Geht es um "was" übergeben wurde (fachlich ungültiger Wert), ist es GraphQlInputException. Geht es um "wer" die Anfrage stellt (fehlende Berechtigung), ist es GraphQlAuthorizationException - unabhängig davon, wie gültig die übergebenen Werte an sich wären.
Teilfehler vs. kompletter Request-Fehler
Alle vier Exception-Klassen führen zu einem Teilfehler: nur das betroffene Feld wird zu null (mit Null-Bubbling nach den Regeln aus Kapitel 7), während Geschwisterfelder in derselben Anfrage normal ausgeführt werden. Ein rein syntaktischer Fehler - eine kaputte Query, die gar nicht erst gegen das Schema validiert - führt dagegen dazu, dass die komplette Anfrage ohne data-Feld fehlschlägt, noch bevor irgendein Resolver läuft.
{
"data": {
"addEventToFavorites": null
},
"errors": [
{
"message": "You must be logged in as a customer to favorite an event.",
"extensions": { "category": "graphql-authorization" }
}
]
}Achtung: Alle vier GraphQL-Exceptions erwarten als ersten Konstruktor-Parameter eine \Magento\Framework\Phrase - erzeugt über __('...'), nie einen rohen String. Das ist keine Stilfrage: __() macht die Fehlermeldung übersetzbar (i18n-CSV-Dateien), ein roher String bleibt in jeder Storefront-Sprache identisch Deutsch bzw. Englisch.
Was im Produktivmodus tatsächlich ankommt
Alle vier vorgestellten Exceptions liefern ihre Nachricht unverändert an den Client - unabhängig vom Deployment-Mode. Das ist bewusst so: Diese Exceptions sind für fachliche, für den Endnutzer verständliche und sichere Meldungen gedacht. Eine gewöhnliche, nicht-GraphQL-spezifische Exception dagegen wird im Produktivmodus zur generischen "Internal server error"-Meldung maskiert, damit keine internen Implementierungsdetails (Stacktraces, Tabellennamen) nach außen dringen - im Developer-Mode bleibt sie dagegen unmaskiert sichtbar, was beim Debuggen in Kapitel 25 wieder aufgegriffen wird.
Tipp: Wer unsicher ist, ob ein Fehlerfall fachlich (also eine der vier GraphQL-Exceptions) oder technisch (eine normale, unmaskierte Exception im Developer-Mode) ist, sollte sich fragen: "Ist das eine Situation, die ein Endnutzer selbst verursachen und verstehen kann?" Eine ungültige Kunden-Eingabe: ja, GraphQL-Exception. Eine fehlgeschlagene Datenbankverbindung: nein, normale Exception durchreichen lassen.
Mit systematischer Fehlerbehandlung ist Block 5 abgeschlossen - die Veranstaltungen-API liest, filtert, schreibt und schützt korrekt. Block 6 widmet sich Performance-Themen: N+1-Probleme, Caching, Datei-Uploads und ACL.