Axios: L'erreur de capture Axios renvoie une erreur javascript et non une réponse du serveur

Créé le 17 juin 2017  ·  87Commentaires  ·  Source: axios/axios

J'essaie d'attraper les erreurs de validation du serveur.

Code:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
    (response) => { console.log(response) },
    (error) => { console.log(error) }
);

Sortie du journal de la console

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Sortie de l'onglet Réseau
{"name":["Le champ du nom est obligatoire."],"parts":["Le champ des pièces est obligatoire."]}

Je devrais voir un objet qui contient la validation de formulaire JSON car c'est la réponse dans mon onglet réseau, je semble obtenir la sortie de capture JS ?

J'ai également essayé ce qui suit :

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error)
});

Même résultat

Plus de gens semblent avoir le même problème en utilisant le même environnement que moi ici.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Version Axios : ^0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Environnement : node v6.4.0, chrome 58, Mac OSX 10.12.4

Commentaire le plus utile

J'ai exactement le même environnement. Essaye ça:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modifiez de console.log(error) à console.log(error.response) en catch .

Vous pouvez également utiliser un intercepteur global et rejeter uniquement le error.response . Le problème est que lorsque le console.log essaie d'afficher l'erreur, la représentation sous forme de chaîne est imprimée, pas la structure de l'objet, vous ne voyez donc pas la propriété .response .

Tous les 87 commentaires

J'ai exactement le même environnement. Essaye ça:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modifiez de console.log(error) à console.log(error.response) en catch .

Vous pouvez également utiliser un intercepteur global et rejeter uniquement le error.response . Le problème est que lorsque le console.log essaie d'afficher l'erreur, la représentation sous forme de chaîne est imprimée, pas la structure de l'objet, vous ne voyez donc pas la propriété .response .

Si quelqu'un se demande comment rejeter uniquement la propriété response , voici comment procéder :

axios.interceptors.response.use((response) => {
    return response;
}, function (error) {
    // Do something with response error
    if (error.response.status === 401) {
        console.log('unauthorized, logging out ...');
        auth.logout();
        router.replace('/auth/login');
    }
    return Promise.reject(error.response);
});

La partie importante est return Promise.reject(error.response);

Cela donne le même résultat si la solution ci-dessus perturbe la syntaxe de votre fichier JS lors de l'indentation ou de la minification :)

.post('ajax/register/otp', this.registerData)
.then(function (response) {
       return otpSent(response)
})
.catch(function (error) {
      console.log(error.response);
 });

@gopal-g ce n'est pas défini pour moi.

Eh bien @pedro-mass dans ce cas, il pourrait n'y avoir aucune réponse du côté serveur. dans mon scénario, ma réponse était JSON lorsqu'une erreur s'est produite, je pouvais obtenir la réponse en utilisant error.response

@gopal-g Si je regarde l'onglet Réseau dans les outils de développement, je peux voir la réponse. C'est une 401 si ça fait une différence.

J'ai la même erreur avec @pedro-mass 's.

voici mon code

async function test () {
try {
  let res = await axios.get('/xxxxx/xxxx')

} catch (e) {
  console.log(e.response) // undefined
}
}

l'utilisation de "error.response" ne fonctionne pas pour moi. Le problème se produit lorsque j'ai déconnecté le serveur de base de données et que mon serveur Web a renvoyé l'erreur 500.

Onglet Réseau dans les outils de développement

code de réponse : 500
corps de la réponse :

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

erreur de la console chromée :

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

version

"axios": "^0.15.3"

Il y a un hic dans catch : si l'erreur se produit avant que la requête ne soit faite, alors dans catch vous n'aurez pas la propriété err.response , car... eh bien.. .il n'y a pas de réponse. Ainsi, le catch attrapera toute erreur. Il en va de même dans des situations comme celle de @fabiorecife lorsqu'il n'y a pas de réponse à cause d'une panne de réseau. Ne traitez pas le err comme une erreur HTTP car ce n'est pas toujours le cas.

@alsofronie alors quelle est la méthode de traitement préférée (en distinguant les uns des autres), par exemple les échecs de contrôle en amont comme 413 ?

Je rencontre un problème similaire - Chrome devtools affiche un 401 , la réponse est {"message":"Identity token has expired"} et je suis catch( (error) => {...}) - mais error.response vide. Je me demande si c'est parce que l'appel OPTIONS précédent associé au GET a un statut de 200 . Que faire dans ce cas et où est le bon endroit pour récupérer le code d'état 401 ?

@robbiemu, je pense que c'est déjà documenté : https://github.com/axios/axios#handling -errors

@mrchief merci pour cela, c'est bien de le revoir. Dans mon cas, cette solution fonctionne dans la plupart des cas, mais le problème actuel que je rencontre est que l'objet error.response est présent, mais les champs sont undefined , tous les appels à des valeurs à l'intérieur du response génère une erreur.

@paolavness Je suggérerais d'ouvrir un nouveau problème au lieu de commenter ici. Peu de problèmes de montres sont fermés. Ou peut-être même le demander sur StackOverflow.

@mrchief Ah c'est fermé, merci de l'avoir signalé. ça ira.

J'ai eu le même problème. En fin de compte, j'ai changé le code d'erreur de 401 à 403 et tout a fonctionné comme je m'y attendais. Je suppose que la raison de l'objet d'erreur vide et de l'erreur javascript qui en résulte a à voir avec cette déclaration que j'ai trouvée dans la documentation pour les erreurs 401 :

"[A 401 error] La réponse doit inclure un champ d'en-tête WWW-Authenticate contenant un défi applicable à la ressource demandée."

Donc, si vous comptez utiliser une erreur 401, vous devez inclure un champ d'en-tête www-authenticate. Si vous ne voulez pas faire cela, utilisez simplement une erreur 403.

Bonjour les gars, j'ai eu ce problème, cependant, je l'ai corrigé en changeant ma configuration Apache pour activer les cors sur mon serveur. Jetez un oeil au lien ci-dessous

https://enable-cors.org/server_apache.html

Vous pouvez déboguer toutes les réponses uniquement avec console.log(JSON.stringify(error))

axios.post(url)
.then((réponse) => {
// quelque chose
})
.catch((réponse) => {
if (response.status == non défini) {
alerte('non autorisé')
}
})

J'ai eu exactement le même problème décrit par @fabiorecife . Je l'ai résolu mais ce n'est pas la solution la plus élégante et je ne comprends pas pourquoi cela est nécessaire.

.catch(error=>{
let errorObject=JSON.parse(JSON.stringify(error));
console.log(errorObject);
dispatch(authError(errorObject.response.data.error));
})

Cela produit les résultats attendus dans la variable errorObject .

@petruscurtu j'ai le même problème! Cela ne fonctionne pas pour moi!
image
Je ne sais pas pourquoi il lance 'pas de contrôle d'accès-autoriser-origine', mais le serveur l'a défini ! L'en-tête de réponse est ok

image

Résolu. L'API auth ne répondait pas au bon en-tête qui doit avoir l'Access-control-allow-origin

@luxueyan Je ne sais pas quel pourrait être le problème car je ne sais pas comment vous gérez CORS sur votre serveur. En ce qui concerne axios, je peux voir un objet de configuration et de demande dans la sortie de votre console. Je pense que vous devriez vérifier cette sortie. Cela peut être lié au format de la réponse que votre serveur renvoie.

@luxueyan Il semble que vous Access-control-allow-origin pour http://localhost:8081 (en supposant qu'il soit configuré sur le serveur avec cette adresse http://10.31.143.32:8080 ?) Pouvez-vous vérifier quelle est l'URL que vous exécutez ce projet à partir de ? Est-ce http://localhost:8081 ? Si ce n'est pas le cas, même si le numéro de port est différent, cela viole les règles du domaine CORS.

@petruscurtu La sortie est 'JSON.parse(JSON.stringify(error))' dans l'intercepteur de réponse. Il n'y a pas de propriété de réponse

@chiefie Je suis sûr que le paramètre 'Access-control-allow-origin' est correct car d'autres api ajax peuvent répondre au bon contenu!Seul le code capcha api va mal。 quand il est expiré, il répond à une erreur avec le statut 478 et axios ne peut pas obtenir le corps de la réponse!

Mettre à jour! C'était l'erreur de l'API du serveur, il n'y avait pas de paramètres cors dans l'en-tête. Maintenant, travaillez bien.

Merci @juliano-barros c'était à cause de l'origine croisée. Maintenant, toutes mes requêtes ajax fonctionnent très bien.

Cette erreur brute est renvoyée chaque fois que le serveur est inaccessible/CORS invalidé.
error.response sera juste undefined .

Je viens de créer une IntegrationError qui contient des données de message, d'état et de réponse... mais toujours en suivant la même structure. De cette façon, je peux découpler les erreurs axios/raw de mes manipulations.

Les gars d'Axios, cela devrait être une erreur HTTP je pense... y compris un error.response .
Cela peut être vérifié comme ci-dessus

Hier, c'était le premier anniversaire de ce numéro. Cela sera-t-il un jour "réparé" ou est-il considéré comme un "non-problème" à ce stade ?

@frostshoxx Je pense donc que c'est un "non-problème". Alors que je rencontre le même problème que tout le monde, je comprends maintenant ce qui se passe et je peux voir qu'il ne s'agit pas d'un bug ou d'un problème, mais simplement de la façon dont le monde fonctionne.

Pour tous ceux qui sont confus (et pour célébrer le premier an de ce problème), laissez-moi vous expliquer ce qui se passe et comment obtenir une réponse de votre serveur.

Comment êtes-vous arrivé ici ?

Il existe de nombreuses raisons pour lesquelles vous pourriez rencontrer le .catch() Wasteland. Parfois, Axios rencontre une erreur au début de la requête. Cela arrive parfois avec les requêtes CORS. Lorsque Axios OPTIONS n'est pas disponible, Axios panique et vous envoie à .catch() avant d'obtenir une réponse du serveur, donc la réponse n'est pas disponible dans ces cas.

Certains d'entre vous pourraient dire : « Non, je le vois dans DevTools, donc la réponse est revenue ! » Ce n'est pas toujours vrai car parfois Axios lance une requête HTTP, rencontre une erreur, s'interrompt et vous envoie à .catch() avant que le serveur ne réponde. Quelques millisecondes après qu'Axios ait exécuté la fonction .catch() , votre serveur peut revenir avec une réponse, qui apparaît dans DevTools car il est toujours à l'écoute de la réponse. Cependant, Axios est terminé depuis longtemps à ce stade, donc le response n'était pas disponible car il n'existait pas au moment où Axios a lancé la fonction .catch() .

Ceux d'entre vous qui reçoivent un message concernant une erreur 4XX ou 5XX du serveur ont de la chance ! Il y a généralement une réponse du serveur à votre disposition car pour obtenir cette erreur, Axios a dû attendre la réponse complète du serveur. Dans ces cas, Axios vous envoie à .catch() avec le response mais il encapsule la réponse dans son propre objet error qu'il crée à la volée.
Donc, si vous obtenez des erreurs 5XX ou 4XX , vous avez probablement la réponse du serveur à votre disposition, mais elle est enfouie DEEP !

Essayez error.response.data.data.message . Il est confirmé que cela fonctionne pour les demandes d'API Laravel qui renvoient des erreurs de serveur.

Utilisateurs non Laravel -- Vous devrez au moins aller à error.response.data pour accéder à la réponse principale du serveur, mais la plupart des serveurs enveloppent leurs réponses dans un autre objet data{} vous obligeant à couche plus profonde, puis accédez enfin à la propriété de réponse souhaitée, comme .message partir de là.

Mais j'ai fait Console.Log et il ne contient aucune réponse !

Ouais je sais, mais essayez juste de sortir error.response.data toute façon juste pour me faire plaisir.

Pour une raison quelconque, Axios modifie la sortie de console.log(error) sur l'objet d'erreur. Je ne sais pas pourquoi ils font cela, mais si vous écrivez plutôt console.log(JSON.stringify(error)) vous verrez tout l'objet dans toute sa splendeur.

Il s'agit d'un JSON sérialisé qui devient difficile à lire après environ 2 couches de profondeur. Vous devez donc copier le tout et le coller dans un prettifyer JSON pour explorer la structure de l'objet d'erreur.


Si vous obtenez une erreur 500 ou une erreur de type 400 (ou vraiment n'importe quel code d'erreur fourni par le serveur) dans Axios, cela signifie que la requête est terminée et que la réponse du serveur est à votre disposition !

Le problème est qu'il est très profond, et parce qu'Axios modifie la sortie de notre console.log(error) que la plupart des gens font pour voir l'objet error{} , la plupart des gens ne savent pas qu'il existe. Mais c'est là !

@VSG24 mec !! c'est une réponse qui sauve :D

fwiw, JSON.stringify(error) bombes en 0.18.0 en raison de références circulaires.

J'ai mis en place un intercepteur qui me donne une réponse du serveur en cas d'erreur

axios.interceptors.response.use(
  response => {
    // do someting on response
    return response
  },
  error => {
    // do someting on errir
    return Promise.reject(error.response.data) // => gives me the server resonse
  }
)
    try {
      const { data } = await htttp.post(login, payload)
      // do someting with data
    } catch (e) {
      console.log(e) // server response data
    }

@alimirayman Cela semble bien fonctionner si nous ne devons pas surveiller chaque demande. Mais, lorsque vous devez suivre chaque demande, il n'est pas raisonnable d'avoir un gestionnaire d'erreurs répété à chaque endroit de mon code. Sauf si j'ai mal compris (ce qui peut être le cas), axios ne devrait pas avoir à s'assurer que le serveur a renvoyé une erreur avant de renvoyer une erreur ?

@hhowe29 utilise circular-json

J'ai trouvé ce fil comme beaucoup d'autres et j'utilise axios avec les modules vue.js et vuex.

Mon action de module vuex détecte l'erreur axios et exécute commit(ERROR_HAPPENED, error) pour exécuter la mutation ERROR_HAPPENED du module vuex. Mais l'erreur arrive sans sa propriété de réponse, ce qui fait que error.response n'est pas défini si j'essaie de définir la réponse sur un état vuex.

Si je console.log(error.response) dans l'action, avant le commit(), je peux voir la réponse. Il est donc probablement mutilé par vuex.

Soit commit(ERROR_HAPPENED, error.response.data) soit vérifiez s'il s'agit d'un 401 dans l'action et exécutez un autre commit en fonction du code d'état. Parce que cette mutilation ne se produit qu'avec un code 401. D'autres erreurs comme 404 ou 500 sont transmises à mes mutations.

Pas mutilé. Vuex ne modifie pas cela, même pas par bug.
Certains types d'erreurs, principalement à l'intérieur des intercepteurs Axios, empêchent cela d'être exposé.

Une mise à jour ?

@AllanPinheiroDeLima désolé pour la réponse tardive, mais je ne pense pas que quiconque écrive un intercepteur à chaque emplacement du code de quiconque. Nous écrivons intercepter une fois sur une base de code et l'utilisons comme classe d'assistance, c'est le numéro 1. Numéro 2, la requête initiale était qu'ils n'avaient pas obtenu _réponse d'erreur du serveur_, à la place, ils ont obtenu l'_erreur javascript_ dans le try catch bloc. il y avait 2 solution une pour changer la façon dont le serveur a répondu à l'erreur ou la façon dont l'interface a détecté l'erreur. axios intercepteur d'erreurs

Oui je suis d'accord. J'ai trouvé une solution à ce problème en effectuant l'intégration dans mon propre serveur à la place d'un keycloak brut. De cette façon, je pouvais intercepter l'erreur dans le serveur, puis en envoyer une lisible au frontal. Je pense que c'est la seule façon de résoudre ce genre de problème pour l'instant :)

J'ai encore le même problème. En utilisant dans Axios interceptor console.log('interceptors', JSON.stringify(error)) j'obtiens ce journal interceptors {"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"},"method":"post","url":"http://localhost:5000/api/autenticacao/login","data":"{\"siglaInstituicao\":\"NEAS\",\"usuario\":\"emersoncpaz\",\"senha\":\"belle1903\"}"},"request":{}} mais chrome devtools Réponse j'ai la bonne réponse de l'api : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) Comment obtenir cette réponse d'axios ?

Une raison pour laquelle les erreurs 5xx ne sont pas gérées par le bloc catch (ne renvoie pas d'objet de réponse) ? Le code d'état 502 apparaît dans la console DevTool mais n'est pas géré par Axios.

Cela a fonctionné pour moi (avec laravel abort helper: abort(500, 'message'))
```
.catch(erreur => {
console.log (erreur.réponse.data.message);
});

```

Quelqu'un a-t-il un exemple de travail complet autre qu'un extrait de code indiquant que cela a fonctionné ? Un extrait de 1 ligne n'aide pas beaucoup si vous n'avez aucune idée de qui ils faisaient référence dans ce fil, où ils ont mis ce bout de code, à quoi ressemble le code de travail final?

J'essaie de détecter l'erreur dans l'inercepteur et, en fonction du code d'erreur, soit terminez la demande avec une redirection si 401 pour se connecter, soit si son 422 laisse la demande revenir au composant appelant pour permettre la mise à jour des erreurs de formulaire.

Des idées?

J'utilise Nuxt axios et mon intercepteur onResponseError ressemble à :

$axios.onResponseError(error => {
    const code = parseInt(error.response && error.response.status)
    console.log(code, 'Axios onResponseError')
    console.log(error.response.status, 'status')
    console.log(error.config, 'config')
    console.log(error.response, 'response')
    // Do something with response error
    if (error.response.status === 401) {
      console.log('unauthorized, logging out ...')
      app.$auth.logout()
      redirect('/login')
    }
    if (code === 400) {
      // redirect('/400')
      console.log(`400 onResponseError`)
    }
    if (code === 408) {
      console.log(`A timeout happened on url onResponseError`)
    }
    if (code === 418) {
      console.log(`A teapot onResponseError`)
    }
    if (code === 428) {
      console.log(`428 onResponseError`)
      // redirect('/login')
    }
    return Promise.reject(error)
  })

Et un exemple d'appel ressemblerait à :

async postRecord (clear = false) {
      try {
        const { r } = await this.$axios.$post(this.endPoint, this.formData)
        console.log(r, 'response')
        // do something with response
      } catch (e) {
        console.log(e, 'error in crud') // server response data
        // i should never get here if error since the interceptor should kill the request if 401
       // for testing this request is returning a 401
      } finally {
        this.submitted = false
      }
    },

Merci,
Dave

Lorsqu'il n'y a pas d'Internet, l'erreur.réponse n'est pas définie - est-ce le meilleur moyen ?

J'obtiens une erreur en texte brut, j'ai dû utiliser ce qui suit pour convertir l'erreur dans un objet.

var errorObj = JSON.parse(JSON.stringify(error));

Cela dépend du serveur et non d'axios, avez-vous essayé de creuser dans le
error.response.status, s'il n'est pas défini, vous savez qu'il s'agit d'un Internet
problème de connexion ou erreur de syntaxe dans votre JS

Le mer. 2 janvier 2019, 15:40 Ibrahim Azhar Armar < [email protected]
a écrit:

J'obtiens une erreur en texte brut, j'ai dû utiliser ce qui suit pour convertir l'erreur en
un objet.

var errorObj = JSON.parse(JSON.stringify(error));

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/axios/axios/issues/960#issuecomment-450896476 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AEETt2r3bt2QCixDlzh4fZvWp_1rPkxuks5u_NMEgaJpZM4N9Ljl
.

@kgrosvenor Je mets le script du serveur en veille et j'attends qu'axios déclenche le délai d'attente. Je crois que le serveur à ce stade ne répond pas, ce qui déclenche le rappel dans axios.

Je reçois le bon message d'erreur, mais la console l'affiche en texte brut, il ne semble donc que le problème de formatage, qui ne semble pas lié au serveur.

Si c'est le cas, j'essaie de comprendre ce qui dans le serveur pourrait être à l'origine de cela ?

Vous atteignez probablement un délai d'attente alors, essayez de vérifier si une "réponse" existe dans l'erreur

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

Le programmeur Java m'envoie un message d'erreur avec une erreur 500 et je ne peux pas gérer ce message. Je lui demande donc de renvoyer le statut 200 avec un message d'erreur en réponse, mais il est en colère contre moi et dit que son client HTTP voit tous les messages avec le statut 500. Il pense que je suis stupide car je ne trouve pas de message d'erreur avec le statut 500. Comment lui expliquer qu'axios ne gère pas le message d'erreur 500 ?

Le programmeur Java m'envoie un message d'erreur avec une erreur 500 et je ne peux pas gérer ce message. Je lui demande donc de renvoyer le statut 200 avec un message d'erreur en réponse, mais il est en colère contre moi et dit que son client HTTP voit tous les messages avec le statut 500. Il pense que je suis stupide car je ne trouve pas de message d'erreur avec le statut 500. Comment lui expliquer qu'axios ne gère pas le message d'erreur 500 ?

En fait, vous devez être capable de gérer l'erreur avec le statut 500, vous pouvez vérifier le statut http en réponse et décider de la manière de le gérer côté client. Ceci est déjà documenté dans ce lien (https://github.com/axios/axios#handling-errors)

Voici comment j'attrape l'erreur 500 du serveur, et cela fonctionne pour moi.

.catch(function (error) {
    var errorObj = JSON.parse(JSON.stringify(error));
    console.log(errorObj);
    if (errorObj.code == 'ECONNABORTED') {
        alert('Connection timed out.');
    }
});

Vous pouvez gérer le statut 500 malgré tout, mais une assez mauvaise pratique pour le renvoyer exprès du côté serveur à mon avis...

Je reçois également error.response non défini, puis j'essaie le code ci-dessous.

axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  // Do something with response error
  let {response} = error;
  // response?.status === 401 es7 way.
  if (response && response.status === 401) {
    // Do logout;
    // Redirect to login;
    return Promise.reject(error.response);
  } 
  else if (error.response){
    // Do something.
    console.log('some API_CLIENT error');
    return Promise.reject(error.response);
  }
 return Promise.reject(error);
});

C'est dommage, la gestion des erreurs est importante.

Comment ça va maintenant ? Je rencontre toujours le même problème avec la version 0.18.0 !

même problème pour moi : @nuxtjs/axios v5.0.0

C'est un bug

Daniel Stern [email protected]于 2019年2月28日周四 04:39写道:

Permettez-moi de résumer cette discussion.

tl;dr :
TOUT LE MONDE L'impossibilité de détecter les erreurs HTTP est un problème.
DÉVELOPPEURS Ne pas être en mesure de détecter les erreurs HTTP n'est pas un problème.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/axios/axios/issues/960#issuecomment-468020991 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAN8CbMHohyuSZHYlcieD_5yUqizpkSYks5vRuzygaJpZM4N9Ljl
.

Vous devez mentionner ce problème dans le README s'il vous plaît, très utile. Merci!

https://github.com/axios/axios/issues/960#issuecomment -320659373

D'accord avec les autres affiches. Avoir un objet avec une structure imprévisible donné à catch fonction du moment où l'erreur se produit n'est pas génial. error.response et JSON.stringify(error) peuvent eux-mêmes générer une erreur en fonction de la cause. L'approche suggérée sur https://github.com/axios/axios#handling -errors n'est pas vraiment éclairante à ce sujet non plus.

Devoir faire toutes ces acrobaties pour renvoyer un message d'erreur flippant est embarrassant en 2019. Cela aurait été embarrassant en 1990. Sérieusement, les gens de JS, intensifiez votre jeu. Apprenez la conception d'API et reconnaissez que vos «décisions créatives» ont coûté à des milliers de personnes d'innombrables heures pour déboguer un gâchis que vous ignorez délibérément.

Pour ceux qui ont du mal avec les références circulaires, vous pouvez faire quelque chose comme ceci :

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

Pour ceux qui ont du mal avec les références circulaires, vous pouvez faire quelque chose comme ceci :

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

Merci mec ! c'est le code qui a bien fonctionné pour moi.

Le problème est dans "lib/core/enhanceError". L'objet de demande est ajouté à l'erreur. Il est logique d'ajouter une réponse à la réponse car il n'y a qu'un seul paramètre dans les API basées sur la promesse (la bibliothèque de requêtes renvoie l'erreur en tant que premier paramètre et la réponse en tant que deuxième). Mais cela n'a aucun sens d'ajouter toute la demande. Le changement de code est très simple https://github.com/geoblink/axios/pull/1/files
Je pourrais ouvrir pr à la branche principale si cela me semble important (je ne le fais pas puisque le sujet est fermé)

vous pouvez créer un wrapper de fonction que vous appellerez à chaque fois lors de la demande

const api = async (uri, data) => {
  try {
    const { data: response } = await axios({
      url: domain + uri,
      method: 'POST',
      data,
    });

    return response.data;
  } catch (error) {
    throw error.response.data;
  }
};

Vous atteignez probablement un délai d'attente alors, essayez de vérifier si une "réponse" existe dans l'erreur

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

Cela a fonctionné pour moi. Merci

l'utilisation de "error.response" ne fonctionne pas pour moi. Le problème se produit lorsque j'ai déconnecté le serveur de base de données et que mon serveur Web a renvoyé l'erreur 500.

Onglet Réseau dans les outils de développement

code de réponse : 500
corps de la réponse :

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

erreur de la console chromée :

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

version

"axios": "^0.15.3"

PAREIL ICI...

Dans mon expérience:

"Modifier de console.log(error) à console.log(error.response) dans catch."

fonctionnait mieux avec console.log(error.response.data) dans catch.

axios.interceptors.response.use(null, erreur => {
renvoyer erreur.réponse ;
});

getClients : async (état) => {
const res = wait axios.get( ${BASE_API}/clients );
console.log('res',res);
si (rés){
state.commit("setClient", res.data);
}
}

Une autre option

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * <strong i="6">@param</strong> axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

Essayer{
Attendez ça.$axios .....
}attraper(e)
{
console.log(e)

}

axios.get("https://......") 
     .then( response => {
          return response
}).catch( () => {
         store.dispatch("errorComponentMethod")   // if there's an error, method is dispatched
})
//////////////////////////////////////
actions : {
      errorComponentMethod(){
              router.push("/errorComponent")     // method routes to error component
      }
}

Grand merci ! A beaucoup aidé!

toujours ce problème. sur le débogueur chrome, la réponse est correcte mais axios renvoie un "Request failed with status code 403" place

J'ai toujours ça et je suis vraiment confus. J'ai essayé de comprendre que ce sont les commentaires ci-dessus - mais pourquoi exactement axios renvoie-t-il undefined lorsqu'il y a une erreur ?
try{ const res = await axios.get("someurl"); return res; } catch(e) { console.log(e); }
res n'est pas défini même si le serveur renvoie une réponse contenant un message expliquant POURQUOI cela n'a pas fonctionné. Et je ne peux pas accéder à ces données... pourquoi ??

** EDIT : j'ai trouvé mon bug - rien de mal pour moi avec axios. Voir mon commentaire deux commentaires plus bas. En bref, mes intercepteurs ne transmettaient pas les données d'erreur via le pipeline axios, donc je devenais toujours indéfini.

@HoogsterInc Regardez les définitions TypeScript ici
tu pourrais faire quelque chose comme ça

try {
   axios.get(...)
} catch (error) {
   if (error.reponse) {
      // http status 4x, 5xx
   } else {
      // network error like timeout, connection refused etc...
   }
}

Merci pour la réponse en essayant d'aider @konstantinblaesi -- j'ai compris mon problème.

Pour moi, j'ai configuré un intercepteur pour vérifier l'authentification de l'utilisateur, qui s'il n'est plus authentifié, envoie un code d'erreur spécifique. Cependant, je ne transmettais pas les données d'erreur lorsque l'erreur ne correspondait pas à un code non authentifié... soupir... stupide erreur. Donc, après avoir vérifié le code d'erreur non authentifié, je me suis assuré de retourner Promise.reject(error); - Cela a résolu mon problème et les données d'erreur sont maintenant complètes.

Vous pouvez utiliser err.toJSON()

catch((err) => {
    console.log(err.toJSON()); // Return error object
});

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

(défini pour le global)

dans le fichier main.js

import axios from 'axios'

var instance = axios.create(
 { validateStatus: function (status) {
    return status < 600; #you can change this with another value
  }
 });

ou
(réglé pour particulier)

  axios.post('/formulas/create', {
       name: "",
       parts: ""
  }, { validateStatus: function (status) {
          return status < 600; // Reject only if the status code is greater than or equal to 500
        }})
    .then( 
   (response) => { console.log(response) },
   (error) => { console.log(error) }
   );

Données de réponse d'erreur Axios et catch 500

const log = console.log;

  updateData(options = {}, flag = false){
    let url = `/opapi/appDownloadGuide/update`;
    let message = '更新成功!';
    let errorMessage = '更新失败!';
    if (flag) {
      message = '添加成功!';
      errorMessage = '添加失败!';
      url = `/opapi/appDownloadGuide/add`;
    }
    axios
    .post(url, options)
    .then(res => {
      // ❓🤔️500 , 在这里拦不住呀?
      log(`res`, res, res.status);
      return res.data;
    })
    .then(json => {
      const {
        code,
        success,
        data,
        errorCode,
        errorHint,
      } = json;
      if(code === 200) {
        this.$message({
          type: 'success',
          message,
        });
        this.init();
      } else{
        this.$message({
          type: 'error',
          message: `${errorMessage}: ${errorHint ? errorHint : ""}`,
        });
      }
    })
    .catch(err => {
      // 👌在这里拦截 error data!
      log(`error.response`, err.response);
      const {
        data,
        status,
        statusText,
      } = err.response;
      this.$message({
        type: "error",
        message: `${statusText}-${status}: ${data || ""}`,
        // message: "不能重复创建",
      });
      console.error(`500 err`, err);
    });
  },

https://stackoverflow.com/questions/38798451/how-to-catch-and-handle-error-response-422-with-redux-axios

J'ai exactement le même environnement. Essaye ça:

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error.response)
});

_Modifier de console.log(error) à console.log(error.response) en catch _.

Vous pouvez également utiliser un intercepteur global et rejeter uniquement le error.response . Le problème est que lorsque le console.log essaie d'afficher l'erreur, la représentation sous forme de chaîne est imprimée, pas la structure de l'objet, vous ne voyez donc pas la propriété .response .

Ne fonctionne pas pour moi

@gopal-g ce n'est pas défini pour moi.

@gopal-g oui même non défini je reçois.

J'utilise Axios 0.19.2. J'ai ajouté la solution de @konstantinblaesi :

Une autre option

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * <strong i="9">@param</strong> axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

Cela a fonctionné pour moi, merci beaucoup @konstantinblaesi ! Je ne comprends pas pourquoi le comportement par défaut d'Axios n'est pas comme ça - le comportement standard consiste à supprimer la partie "message" de l'erreur d'origine, ce qui, à mon avis, est la partie la plus importante !

Juste pour être clair, dans mon application, mon serveur renvoie une erreur 400 (qui devrait être une réponse):

% curl -X POST http://my-server/api -d '{"foo": "bar"}'
{"status": 400, "message": "missing param XYZ"}

et sans ce correctif, j'obtiens d'Axios un objet d'erreur qui ne contient que name , stack , config (qui contient la demande d'origine) et aucune "réponse". Mais avec ce correctif, l'erreur contient la propriété message correcte du serveur.

Quant à savoir pourquoi il n'y a pas de propriété "response" sans ce correctif, cela semble être lié à settle dans axios.js autour de la ligne 1171 :

        module.exports = function settle(resolve, reject, response) {
          var validateStatus = response.config.validateStatus;
          if (!validateStatus || validateStatus(response.status)) {
            resolve(response);
          } else {
            reject(createError(
              'Request failed with status code ' + response.status,
              response.config,
              null,
              response.request,
              response
            ));
          }
        };

et vous pouvez voir qu'il ne passe pas par response.message lors de la création de l'erreur. De plus, dans mon application, je ne vois pas la réponse dans error.response , il n'y a pas une telle propriété -- je ne comprends pas cela. Mais de toute façon, le correctif ci-dessus fonctionne pour moi.

J'essaie d'attraper les erreurs de validation du serveur.

Code:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
  (response) => { console.log(response) },
  (error) => { console.log(error) }
);

Sortie du journal de la console

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Sortie de l'onglet Réseau
{"name":["Le champ du nom est obligatoire."],"parts":["Le champ des pièces est obligatoire."]}

Je devrais voir un objet qui contient la validation de formulaire JSON car c'est la réponse dans mon onglet réseau, je semble obtenir la sortie de capture JS ?

J'ai également essayé ce qui suit :

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error)
});

Même résultat

Plus de gens semblent avoir le même problème en utilisant le même environnement que moi ici.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Version Axios : ^0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Environnement : node v6.4.0, chrome 58, Mac OSX 10.12.4

axios.post('/formules/créer', {
Nom: "",
les pièces: ""
})
.ensuite(
(réponse) => { console.log (réponse) },
).catch(err => consol.log(err.response.data)});

error.response est un objet, il affichera [object,object] dans le journal de la console.
vous devez utiliser error.reposne.data pour accéder au message d'erreur.
référez-vous : https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

@chandukasm oui mais dans mon cas je n'ai _pas_ de error.response -- il n'est pas défini, même si la demande a été envoyée et la réponse reçue par express. Voir aussi mon commentaire ci-dessus; le message est ignoré (remplacé par un message générique) même lorsqu'une réponse existe.

error.response est un objet, il affichera [object,object] dans le journal de la console.
vous devez utiliser error.reposne.data pour accéder au message d'erreur.
référez-vous : https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

si vous voyez [object,object] sur console.log, faites simplement JSON.stringify(error.response) pour voir l'erreur réelle.

Il n'y a pas d'objet error.response .

return this.$axios
  .post(postUrl, payload, { responseType: 'json' })
  .then(
    (response) => {
      this.message = `RESP: ${JSON.stringify(response)}`;
    },
    (reason) => {
      this.message = `REAS: ${JSON.stringify(reason)}`;
    }
  )
  .catch((err) => {
    this.message = `CATCH: ${JSON.stringify(err)}`;
  });

payload contient une mauvaise valeur volontairement pour déclencher HTTP 422, qui dans Postman fonctionne comme prévu et le serveur (LB4) renvoie une erreur complète au format JSON expliquant où les données d'entrée étaient erronées, mais dans axios, l'objet error.response n'est pas défini .

Cette page vous a été utile?
0 / 5 - 0 notes