web-dev-qa-db-fra.com

L'instruction Catch ne détecte pas l'erreur levée

Pour une raison quelconque, ce code me donne une erreur d'exception non capturée. Il semble que le bloc catch n'attrape pas l'erreur. Les blocs try catch ont-ils une portée telle que je ne peux pas lancer d'erreur dans une fonction imbriquée, puis m'attendre à ce qu'il soit capturé par une instruction catch portée plus haut dans la chaîne? Certaines des données sensibles de l'application dans laquelle je travaille ont été supprimées, mais il s'attendait à ce que leadInfo [0/1] soit une chaîne alphanumérique de 32 caractères que je tire des paramètres d'URL.

Le problème sous-jacent est ici avec mon AJAX appel renvoyant une erreur de l'API et cette erreur n'est pas gérée correctement dans l'application. D'où la nécessité de l'instruction throw. Le AJAX l'appel se termine bien et renvoie un objet JSON qui ne contient pas l'adresse e-mail en tant que propriété, j'ai donc besoin de gérer cela d'une manière qui modifie la page pour refléter cela.

    jQuery(document).ready(function(){
        try {
            url = "http://api.com/api/v1/lead/" + leadInfo[1]

            jQuery.ajax({
                type: 'GET',
                contentType: 'application/json',
                url: url,
                dataType : 'jsonp',
                success: function (result) {

                    result = jQuery.parseJSON(result);

                    if(!result.data.email){
                        throw ('New exception');
                    }
                    console.log(result);
                    jQuery('.email').html(result.data.email);
                }
            });


            jQuery('.surveryButton').click(function(){
                window.location.replace("http://" + pgInventory.Host + pgInventory.path + leadInfo[0] + "&curLeadId=" + leadInfo[1] + "&curViewedPages=0");
            });
        }
        catch(err) {
            jQuery('.email').html('your e-mail address');
            jQuery('#arrowContent').remove();
        }
});
24
Xenology

La raison pour laquelle votre try catch le bloc échoue car une requête ajax est asynchrone. Le bloc try catch s'exécutera avant l'appel Ajax et enverra la demande elle-même, mais l'erreur est levée lorsque le résultat est renvoyé, AT A LATER POINT IN TIME.

Quand le try catch le bloc est exécuté, il n'y a pas d'erreur. Lorsque l'erreur est levée, il n'y a pas de try catch. Si tu as besoin try catch pour les requêtes ajax, mettez toujours ajax try catch bloque à l'intérieur du callback success, JAMAIS à l'extérieur.

Voici comment procéder:

success: function (result) {
    try {
      result = jQuery.parseJSON(result);

      if (!result.data.email) {
         throw ('New exception');
      }
      console.log(result);
      jQuery('.email').html(result.data.email);
    } catch (exception) {
      console.error("bla");
    };
}
57
flavian

Le problème est que ajax est asynchrone par définition. Votre exception n'est pas levée depuis la fonction $.ajax, Mais depuis la fonction callback en cas de succès (qui est déclenchée ultérieurement).

Vous devez également lui donner un paramètre error: function(data) {} pour gérer les erreurs de réponse du serveur, et en outre, vous devez placer le bloc try/catch inside la fonction de rappel.

Si vous voulez vraiment l'attraper en dehors du rappel, vous devriez envisager d'appeler une fonction plutôt que de lever une exception, car je ne vois pas comment cela peut être fait.

1
MarioDS

En raison de la nature asynchrone des méthodes de rappel en javascript, le contexte de la fonction lançant l'erreur est différent de celui d'origine. Vous devez procéder de cette façon:

success: function (result) {
  try {
    result = jQuery.parseJSON(result);
    if(!result.data.email){
      throw ('New exception');
    }
    console.log(result);
    jQuery('.email').html(result.data.email);
  }
  catch(err) {
    // Dealing with the error
  }
}

Je vous suggère de jeter un œil à cet excellent article sur les contextes (très particuliers) , fermetures et liaisons en Javascript.

1
jap1968