web-dev-qa-db-fra.com

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

J'ai une action qui envoie une demande POST au serveur afin de mettre à jour le mot de passe d'un utilisateur, mais je ne peux pas gérer l'erreur dans le bloc catch chaî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
  }
})

Quand je me connecte l'erreur c'est 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 inconsciemment commis une erreur quelque part? Parce que je gère d’autres erreurs provenant de demandes différentes, cela va bien, mais je n'arrive pas à résoudre ce problème.

35
Phillip Boateng

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

De la docs:

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: {}
}

Donc, la catch(error => ) est en réalité juste catch(response => )

MODIFIER:

Je ne comprends toujours pas pourquoi la consignation de l'erreur renvoie ce message de pile. J'ai essayé de le connecter comme ça. Et alors vous pouvez réellement voir que c'est un objet.

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

EDIT2:

Après un peu plus de recherche ceci est ce que vous essayez d’imprimer. Quel est un objet d'erreur Javascipt. Axios améliore ensuite cette erreur avec la configuration, le code et la réponse comme this .

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'));
29
Jeroen Wienk

Exemple

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

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

 enter image description here

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

26
Steven Leggett

J'ai aussi été perplexe pendant un moment. Je ne reviendrai pas trop sur les choses, mais je pensais qu'il serait utile pour les autres d'ajouter mes 2 centimes.

La error dans le code ci-dessus est de type Error. Ce qui se passe, c'est que la méthode toString est appelée sur l'objet d'erreur parce que vous essayez d'imprimer quelque chose sur la console. Ceci est implicite et résulte de l'écriture sur la console. Si vous regardez le code de toString sur l'objet d'erreur.

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

Comme vous pouvez le voir ci-dessus, il utilise les éléments internes pour construire la chaîne à afficher sur la console. 

Il y a de très bons docs sur mozilla. 

2
Ryan-Neal Mes

Vous pouvez utiliser l'instruction inline if else comme ceci:

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