Behandlung von Fehlern mit react-apollo useMutation hook

10

Ich habe versucht, mich mit diesem Problem auseinanderzusetzen, aber keine eindeutige Antwort darauf gefunden. Ich versuche, eine Anmeldemutation mit dem useMutation-Hook auszuführen.

TLDR; Ich möchte wissen, was genau der Unterschied zwischen dem in Optionen übergebenen onError und dem Fehler ist, den mir die useMutation gegeben hat

Hier ist mein Code-Snippet

const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, {
        variables: {
            email,
            password
        },
        onError(err) {
            console.log(err);
        },
});

Auf der Serverseite habe ich eine voreingestellte / fest codierte E-Mail, die für die Anmeldung verwendet wird, und ich verwende weder Apollo noch einen anderen Client. Im Resolver dieser Login-Mutation gebe ich einfach einen Fehler aus, wenn die E-Mail-Adresse nicht dieselbe ist

throw new Error('Invalid Email');

Jetzt möchte ich diesen Fehler clientseitig behandeln (Reagieren). Ich mache mir jedoch Sorgen, wenn ich den vom useMutation-Hook zurückgegebenen 'Fehler' verwende und versuche, den Fehler auf diese Weise anzuzeigen

render() {
...
{error && <div> Error occured </div>}
...
}

Der Fehler wird in der Benutzeroberfläche aktualisiert, aber React zeigt mir sofort einen Bildschirm mit nicht behandelter Ablehnung (Fehler): Graphql-Fehler: My-custom-error-message

Wenn ich jedoch onError verwende, das in Optionen zur Verwendung der Mutate-Funktion übergeben wurde, wird mir dieser Bildschirm nicht angezeigt, und ich kann mit dem Fehler tun, was ich will.

Ich möchte wissen, was genau der Unterschied zwischen dem in Optionen übergebenen onError und dem von useMutation angegebenen Fehler ist und warum React mir diesen Fehlerbildschirm anzeigt, wenn onError nicht verwendet wird.

Vielen Dank!

d_bhatnagar
quelle

Antworten:

32

Apollo stellt über seine API zwei Arten von Fehlern bereit : GraphQL-Fehler , die als Teil der Antwort zurückgegeben errorswerden data, sowie Netzwerkfehler, die auftreten, wenn eine Anforderung fehlschlägt. Ein Netzwerkfehler tritt auf, wenn ein Server nicht erreicht werden kann oder wenn der Antwortstatus nicht 200 ist. Abfragen, die errorsin der Antwort enthalten sind, können weiterhin den Status 200 haben. Eine ungültige Abfrage führt jedoch beispielsweise dazu ein 400-Status und ein Netzwerkfehler in Apollo Client.

Apollo Client bietet vier verschiedene Möglichkeiten, um Mutationsfehler zu behandeln:

1.) Das Aufrufen der mutatevom Hook zurückgegebenen Funktion gibt ein Versprechen zurück. Wenn die Anforderung erfolgreich ist, wird das Versprechen lösen zu einem Antwortobjekt , das das enthält datavom Server zurückgegeben. Wenn die Anforderung fehlschlägt, wird das Versprechen mit dem Fehler abgelehnt . Aus diesem Grund wird in der Konsole die Meldung "Nicht behandelte Ablehnung" angezeigt. Sie müssen das abgelehnte Versprechen bearbeiten.

login()
  .then(({ data }) => {
    // you can do something with the response here
  })
  .catch(e => {
    // you can do something with the error here
  })

oder mit asynchroner / warten-Syntax:

try {
  const { data } = await login()
} catch (e) {
  // do something with the error here
}

Standardmäßig lehnt das Versprechen entweder GraphQL-Fehler oder Netzwerkfehler ab. Wenn Sie die errorPolicy auf ignoreoder setzen all, wird das Versprechen nur bei Netzwerkfehlern zurückgewiesen. In diesem Fall ist der Zugriff auf die GraphQL-Fehler weiterhin über das Antwortobjekt möglich, das Versprechen wird jedoch aufgelöst.

2.) Die einzige Ausnahme zu dem oben genannten tritt auf, wenn Sie eine onErrorFunktion bereitstellen . In diesem Fall wird das Versprechen immer aufgelöst, anstatt es abzulehnen. Wenn jedoch ein Fehler auftritt, onErrorwird es mit dem resultierenden Fehler aufgerufen. Das von errorPolicyIhnen festgelegte gilt auch hier - onErrorwird immer für Netzwerkfehler aufgerufen, aber nur mit GraphQL-Fehlern, wenn die Standardeinstellung errorPolicyvon verwendet wird none. Die Verwendung onErrorentspricht dem Abfangen des abgelehnten Versprechens. Der Fehlerhandler wird lediglich von der Aufrufstelle der mutateFunktion zur Aufrufstelle des Hooks verschoben.

3.) Zusätzlich zur mutateFunktion gibt der useMutationHook auch ein Ergebnisobjekt zurück. Dieses Objekt macht auch alle Fehler sichtbar, die beim Ausführen der Mutation auftreten. Im Gegensatz zu den oben beschriebenen Fehlerbehandlungsfunktionen errorrepräsentiert dieses Objekt den Anwendungsstatus . Sowohl die errorals auch datadie auf diese Weise belichteten Objekte dienen als Annehmlichkeit. Sie sind gleichbedeutend damit:

const [mutate] = useMutation(YOUR_MUTATION)
const [data, setData] = useState()
const [error, setError] = useState()
const handleClick = async () => {
  try {
    const { data } = await mutate()
    setData(data)
  catch (e) {
    setError(e)
  }
}

Ein solcher Fehlerstatus kann hilfreich sein, wenn Ihre Benutzeroberfläche die Tatsache widerspiegeln soll, dass ein Fehler vorliegt. Sie können beispielsweise die Farbe eines Elements ändern, bis die Mutation fehlerfrei ausgeführt wird. Anstatt das obige Boilerplate selbst schreiben zu müssen, können Sie einfach das bereitgestellte Ergebnisobjekt verwenden.

const [mutate, { data, error }] = useMutation(YOUR_MUTATION)

HINWEIS: Sie können zwar den Status des exponierten Fehlers verwenden, um Ihre Benutzeroberfläche zu aktualisieren, dies ist jedoch kein Ersatz für die tatsächliche Behandlung des Fehlers. Sie müssen entweder einen onErrorRückruf oder catchden Fehler angeben, um Warnungen vor einer nicht behandelten Ablehnung eines Versprechens zu vermeiden.

4.) Schließlich können Sie auch Apollo-Link-Fehler verwenden , um eine globale Fehlerbehandlung für Ihre Anforderungen hinzuzufügen . Auf diese Weise können Sie beispielsweise einen Fehlerdialog anzeigen, unabhängig davon, woher die Anforderung in Ihrer Anwendung stammt.

Welche dieser Methoden Sie in Ihrer Anwendung verwenden, hängt stark davon ab, was Sie tun möchten (global oder lokal, Status oder Rückruf usw.). Die meisten Anwendungen verwenden mehr als eine Methode zur Fehlerbehandlung.

Daniel Rearden
quelle
Danke für die Erklärung ! Upvoted!
Hyphæne Ohmen