64 votes

Comment attraper et gérer la réponse d'erreur 422 avec Redux/Axios ?

J'ai une action qui fait un POST au serveur afin de mettre à jour le mot de passe d'un utilisateur, mais je ne parviens pas à gérer l'erreur dans le bloc catch enchaîné.

return axios({
  method: 'post',
  data: {
    password: currentPassword,
    new_password: newPassword
  },
  url: `path/to/endpoint`
})
.then(response => {
  dispatch(PasswordUpdateSuccess(response))
})
.catch(error => {
  console.log('ERROR', error)
  switch (error.type) {
    case 'password_invalid':
      dispatch(PasswordUpdateFailure('Incorrect current password'))
      break
    case 'invalid_attributes':
      dispatch(PasswordUpdateFailure('Fields must not be blank'))
      break
  }
})

Lorsque je consigne l'erreur, voici ce que je vois :

Error Logged

Lorsque je vérifie l'onglet réseau, je peux voir le corps de la réponse, mais pour une raison quelconque, je ne peux pas accéder aux valeurs !

Network Tab

Ai-je commis une erreur sans le savoir ? Parce que je gère bien d'autres erreurs provenant de requêtes différentes, mais je n'arrive pas à résoudre celle-ci.

62voto

Steve Points 388

Exemple

getUserList() {
    return axios.get('/users')
      .then(response => response.data)
      .catch(error => {
        if (error.response) {
          console.log(error.response);
        }
      });
  }

Vérifiez l'objet d'erreur pour la réponse, il inclura l'objet que vous recherchez afin que vous puissiez faire error.response.status

enter image description here

https://github.com/mzabriskie/axios#handling-errors

52voto

Jeroen Wienk Points 1097

Axios est probablement en train d'analyser la réponse. J'accède à l'erreur comme ceci dans mon code :

axios({
  method: 'post',
  responseType: 'json',
  url: `${SERVER_URL}/token`,
  data: {
    idToken,
    userEmail
  }
})
 .then(response => {
   dispatch(something(response));
 })
 .catch(error => {
   dispatch({ type: AUTH_FAILED });
   dispatch({ type: ERROR, payload: error.data.error.message });
 });

Dans la documentation :

La réponse à une demande contient les informations suivantes.

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the headers that the server responded with
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {}
}

Ainsi, le catch(error => ) est en fait juste catch(response => )

EDIT :

Je ne comprends toujours pas pourquoi l'enregistrement de l'erreur renvoie ce message de pile. J'ai essayé de l'enregistrer comme ceci. Et là, on peut voir que c'est un objet.

console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));

EDIT2 :

Après quelques recherches supplémentaires ce est ce que vous essayez d'imprimer. Qui est un objet d'erreur Javascipt. Axios enrichit ensuite cette erreur avec la configuration, le code et la réponse comme suit ce .

console.log('error', error);
console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));
console.log('getOwnPropertyNames', Object.getOwnPropertyNames(error));
console.log('stackProperty', Object.getOwnPropertyDescriptor(error, 'stack'));
console.log('messageProperty', Object.getOwnPropertyDescriptor(error, 'message'));
console.log('stackEnumerable', error.propertyIsEnumerable('stack'));
console.log('messageEnumerable', error.propertyIsEnumerable('message'));

2voto

Ryan-Neal Mes Points 2973

J'ai également été bloqué sur ce point pendant un certain temps. Je ne vais pas trop m'étendre sur le sujet, mais j'ai pensé qu'il serait utile aux autres d'ajouter mon grain de sel.

Le site error dans le code ci-dessus est de type Error . Ce qui se passe, c'est que le toString est appelée sur l'objet d'erreur parce que vous essayez d'imprimer quelque chose sur la console. C'est implicite, un résultat de l'écriture sur la console. Si vous regardez le code de toString sur l'objet error.

Error.prototype.toString = function() {
  'use strict';

  var obj = Object(this);
  if (obj !== this) {
    throw new TypeError();
  }

  var name = this.name;
  name = (name === undefined) ? 'Error' : String(name);

  var msg = this.message;
  msg = (msg === undefined) ? '' : String(msg);

  if (name === '') {
    return msg;
  }
  if (msg === '') {
    return name;
  }

  return name + ': ' + msg;
};

Vous pouvez donc voir ci-dessus qu'il utilise les internes pour construire la chaîne à afficher dans la console.

Il y a de grandes docs sur ça sur mozilla.

1voto

Anton Artemev Points 577

Vous pouvez utiliser l'instruction if else en ligne comme suit :

.catch(error => {
    dispatch({
        type: authActions.AUTH_PROCESS_ERROR,
        error: error.response ? error.response.data.code.toString() : 'Something went wrong, please try again.'
    }); 
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X