Gestione degli errori con hook di response-apollo useMutation


10

Ho cercato di risolvere il problema ma non ho trovato una risposta forte. Sto cercando di eseguire una mutazione di accesso utilizzando il hook useMutation.

TLDR; Voglio sapere qual è esattamente la differenza tra le opzioni onError passate e l'errore dato da useMutation

Ecco il mio frammento di codice

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

Sul lato server, ho un'e-mail preimpostata / codificata utilizzata per l'accesso e non sto usando Apollo o nessun altro client. Nel risolutore di questa mutazione di accesso, lancio semplicemente un errore se l'e-mail non è la stessa usando

throw new Error('Invalid Email');

Ora voglio gestire questo errore sul lato client (React). Ma la mia preoccupazione è che se uso l '"errore" restituito dal hook useMutation e provo a mostrare l'errore in questo modo

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

l'errore viene aggiornato nell'interfaccia utente ma immediatamente React mi mostra una schermata con rifiuto non gestito (errore): errore Graphql: messaggio di errore My-custom-

Ma se uso onError nelle opzioni passate per usare la funzione Mutate, allora non mi mostra questa schermata e posso fare quello che voglio con l'errore.

Voglio sapere qual è esattamente la differenza tra le opzioni onError passate nelle opzioni e l'errore fornite da useMutation e perché React mi mostra quella schermata di errore quando onError non viene utilizzato.

Grazie!

Risposte:


33

Apollo espone due tipi di errori attraverso la sua API: errori GraphQL , che vengono restituiti come parte della risposta come errors, insieme data, ed errori di rete che si verificano quando una richiesta fallisce. Si verificherà un errore di rete quando non è possibile raggiungere un server o se lo stato della risposta è diverso da 200 richiesteerrors nella risposta possono comunque avere uno stato di 200. Ma una query non valida, ad esempio, comporterà uno stato 400 e un errore di rete in Apollo Client.

Apollo Client offre in realtà quattro modi diversi per gestire gli errori di mutazione:

1.) Chiamare la mutatefunzione restituita dall'hook restituisce una Promessa. Se la richiesta ha esito positivo, Promise si risolverà in un oggetto risposta che include il datareso dal server. Se la richiesta fallisce, la promessa verrà rifiutata con l'errore. Questo è il motivo per cui viene visualizzato un messaggio "Rifiuto non gestito" nella console: è necessario gestire la promessa rifiutata.

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

o con sintassi asincrona / wait:

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

Per impostazione predefinita, la promessa rifiuterà su entrambi errori GraphQL o errori di rete. Impostando errorPolicy su ignoreo all, comunque, solo Promessa rifiuta gli errori di rete. In questo caso, gli errori GraphQL saranno comunque accessibili tramite l'oggetto response, ma Promise si risolverà.

2.) L'unica eccezione a quanto sopra si verifica quando si fornisce una onErrorfunzione. In questo caso, la Promessa si risolverà sempre invece di rifiutare, ma se si verifica un errore, onErrorverrà chiamato con l'errore risultante. L' errorPolicyimpostazione impostata si applica anche qui: onErrorverrà sempre chiamata per gli errori di rete ma verrà chiamata solo con errori GraphQL quando si utilizza l'impostazione predefinita errorPolicydi none. L'uso onErrorequivale a catturare la Promessa rifiutata: sposta semplicemente il gestore degli errori dal sito di chiamata della mutatefunzione al sito di chiamata dell'hook.

3.) Oltre alla mutatefunzione, l' useMutationhook restituisce anche un oggetto risultato. Questo oggetto espone anche eventuali errori riscontrati durante l'esecuzione della mutazione. A differenza delle funzioni del gestore errori che abbiamo scritto sopra, questo erroroggetto rappresenta lo stato dell'applicazione . Sia l' errore dataoggetti esposti questo esiste modo per comodità. Sono equivalenti a fare questo:

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)
  }
}

Avere uno stato di errore come questo può essere utile quando vuoi che la tua UI rifletta il fatto che c'è un errore. Ad esempio, è possibile modificare il colore di un elemento fino a quando la mutazione non viene eseguita senza errori. Invece di dover scrivere tu stesso la suddetta piastra della caldaia, puoi semplicemente usare l'oggetto risultato fornito.

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

NOTA: sebbene sia possibile utilizzare lo stato di errore esposto per aggiornare l'interfaccia utente, farlo non è un sostituto per la gestione effettiva dell'errore. È necessario fornire una onErrorrichiamata ocatch l'errore per evitare avvisi relativi a un rifiuto Promise non gestito.

4.) Infine, puoi anche usare apollo-link-error per aggiungere global gestione errori per le tue richieste. Ciò consente, ad esempio, di visualizzare una finestra di dialogo di errore indipendentemente dal punto in cui l'applicazione ha avuto origine la richiesta.

Quale di questi metodi usi nella tua applicazione dipende fortemente da cosa stai cercando di fare (globale vs locale, stato vs callback, ecc.). La maggior parte delle applicazioni utilizzerà più di un metodo di gestione degli errori.


Grazie per la spiegazione ! Votato!
Hyphæne Ohmen,

Spiegazione eccezionale e completa. Hai guadagnato un alto voto.
David Fernandez
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.