web-dev-qa-db-fra.com

Gestion de l'erreur Axios dans React

J'ai un composant React qui appelle une fonction getAllPeople:

componentDidMount() {
   getAllPeople().then(response => {
      this.setState(() => ({ people: response.data }));
    });
  } 

getAllPeople est dans mon module api:

export function getAllPeople() {
  return axios
    .get("/api/getAllPeople")
    .then(response => {
      return response.data;
    })
    .catch(error => {
      return error;
    });
}

Je pense que c'est une question très basique, mais en supposant que je veux gérer l'erreur dans mon composant racine (dans ma méthode componentDidMount), pas dans la fonction api, comment ce composant racine sait-il si oui ou non, l'appel axios renvoie une erreur? C'est à dire. quelle est la meilleure façon de gérer les erreurs provenant d'une promesse axios?

8
GluePear

La fonction getAllPeople renvoie déjà les données ou le message d'erreur de votre appel axios. Ainsi, dans componentDidMount, vous devez vérifier la valeur de retour de votre appel à getAllPeople pour décider si c'est une erreur ou des données valides qui ont été renvoyées.

componentDidMount() {
   getAllPeople().then(response => {
      if(response!=error) //error is the error object you can get from the axios call
         this.setState(() => ({ people: response}));
      else { // your error handling goes here
       }
    });
  } 

Si vous souhaitez renvoyer une promesse de votre API, vous ne devez pas résoudre la promesse retournée par votre appel axios dans l'API. Au lieu de cela, vous pouvez effectuer les opérations suivantes:

export function getAllPeople() {
  return axios.get("/api/getAllPeople");
}

Ensuite, vous pouvez résoudre dans componentDidMount.

componentDidMount() {
   getAllPeople()
   .then(response => {          
         this.setState(() => ({ people: response.data}));
     })
   .catch(error => { // your error handling goes here}
  } 
8
palsrealm

Meilleure façon de gérer erreur API avec la méthode de capture Promise *.

axios.get(people)
    .then((response) => {
        // Success
    })
    .catch((error) => {
        // Error
        if (error.response) {
            // The request was made and the server responded with a status code
            // that falls out of the range of 2xx
            // console.log(error.response.data);
            // console.log(error.response.status);
            // console.log(error.response.headers);
        } else if (error.request) {
            // The request was made but no response was received
            // `error.request` is an instance of XMLHttpRequest in the 
            // browser and an instance of
            // http.ClientRequest in node.js
            console.log(error.request);
        } else {
            // Something happened in setting up the request that triggered an Error
            console.log('Error', error.message);
        }
        console.log(error.config);
    });
9
Sagar Gavhane

Ma suggestion est d'utiliser une fonctionnalité de pointe de React. Limites d'erreur

Ceci est un exemple d'utilisation de cette fonctionnalité par Dan Abramov. Dans ce cas, vous pouvez encapsuler votre composant avec ce composant de limite d'erreur. La particularité pour détecter l'erreur dans axios est que vous pouvez utiliser intercepteurs pour détecter les erreurs d'API. Votre composant de limite d'erreur pourrait ressembler

import React, { Component } from 'react';

const errorHandler = (WrappedComponent, axios) => {
  return class EH extends Component {
    state = {
      error: null
    };

    componentDidMount() {
      // Set axios interceptors
      this.requestInterceptor = axios.interceptors.request.use(req => {
        this.setState({ error: null });
        return req;
      });

      this.responseInterceptor = axios.interceptors.response.use(
        res => res,
        error => {
          alert('Error happened');
          this.setState({ error });
        }
      );
    }

    componentWillUnmount() {
      // Remove handlers, so Garbage Collector will get rid of if WrappedComponent will be removed 
      axios.interceptors.request.eject(this.requestInterceptor);
      axios.interceptors.response.eject(this.responseInterceptor);
    }

    render() {
      let renderSection = this.state.error ? <div>Error</div> : <WrappedComponent {...this.props} />
      return renderSection;
    }
  };
};

export default errorHandler;

Ensuite, vous pouvez envelopper votre composant racine en passant l'instance axios avec

errorHandler(Checkout, api)

Par conséquent, vous n'avez pas du tout besoin de penser aux erreurs à l'intérieur de votre composant.

Vous pouvez vérifier la réponse avant de la définir sur state. Quelque chose comme

componentDidMount() {
   getAllPeople().then(response => {
       // check if its actual response or error
        if(error) this.setState(() => ({ error: response }));
        else this.setState(() => ({ people: response}));
    });
  }

Il s'appuie sur le fait que axios renverra différents objets pour le succès et les échecs.

0
Hozefa