Apprendre Javascript pour rendre vos pages Web interactives

Auteur: Mohamed CHINY Durée necessaire pour le cours de Apprendre Javascript pour rendre vos pages Web interactives Niveau recommandé pour le cours de Apprendre Javascript pour rendre vos pages Web interactives Supports vidéo disponibles pour ce cours Exercices de renforcement disponibles pour ce cours Quiz disponible pour ce cours

Page 23: Gestion des exceptions

Toutes les pages

Les erreurs en programmation

Il n'est pas rare que quand on veut exécuter un programme Javascript, les choses ne se passent pas comme prévu. En effet, les erreurs sont très courantes en programmation. Il y'en a qui sont dues au développeur lui même suite un manque de concentration ou un erreur de frappe, et d'autres surviennent accidentellement même si notre code semble bien fait.

De toute façon, la première chose à vérifier pour que le programme soit propre, c'est la syntaxe et la logique (algorithme), bien que l’algorithme devient de plus en plus intuitif et s'intègre systématiquement à la phase de développement avec l'expérience, mais il est courant de dire: "bien que ça marche, j'aurais pu le faire autrement".

L'essentiel dans cette partie, est de voir une autre façon de gérer son code et éviter les erreurs qui peuvent interrompre son exécution.

La gestion des exceptions

Au sein de la plupart des langages de programmation orientés objet (ou prototype) la notion d'exception est omniprésente. En effet, dans cette catégorie de langages on préfère parler d'exception plutôt que d'erreurs.

En Javascript, une erreur est lancée en tant qu'exception et attend qu'elle soit gérée. Si sa gestion est faite convenablement, alors le programme continue de s’exécuter, sinon l'erreur devient un bug qui compromet le bon déroulement de l’exécution.

Bloc try catch

La gestion des exceptions est faite grâce au bloc try catch. Cela signifie qu'on demande au moteur Javascript (interpréteur) d'essayer d’exécuter un bout de code. Si tout va bien alors tant mieux, sinon on doit attraper (ou détourner) l'erreur et faire un traitement alternatif.

Nous allons essayer de survoler rapidement la gestion d'exception en Javascript sans trop entrer dans les détails.

Exemple:
a=10;
b=2;
c==a/b;
alert(c);
Bien que l'exemple n'est pas très méthodique, mais l’essentiel est de savoir comment gérer les erreurs (prévisibles et imprévisibles).

Il s'agit là d'une simple division de 10 par 2. Mais au lieux de mettre c=a/b; on a mis c==a/b. Ce qui représente une erreur (souvent commises par inadvertance). Le programme ne s’exécutera donc pas.

Essayons maintenant ce code:
a=10;
b=2;
try{
   c==a/b;
   alert(c);
}
catch(e){
   alert("Erreur!");
}
La même erreur est commise, mais cette fois on obtient le message "Erreur!" dans la boite de dialogue alert(). Que s'est il passé au juste?

En fait, l'interpréteur Javascript exécute le code ligne par ligne. S'il y a une erreur dans une ligne, l’exécution est interrompue. Ici, l’interpréteur entre dans le bloc try et essaie d’exécuter les instructions entre les accolades. La première instruction c==a/b; cause une erreur. Alors, l'exécution de la suite du bloc try est suspendue, et une exception est automatiquement lancée. Interpréteur cherche alors le premier bloc catch pour l’exécuter. catch reçoit comme paramètre l'objet exception représenté dans cet exemple par le nom e. On dit alors que l'exception est interceptée ou attrapée.

Dans quel cas on aura vraiment besoin de gérer les exception?

La règle générale dit que la gestion des exceptions est recommandée partout pour gérer les erreurs. Cependant, en Javascript elle est souvent utilisée pour détourner les problèmes de compatibilité.

En effet, bien que Javascript est reconnu par tous les navigateurs, il y a des fois où une syntaxe n'est pas perçue de la même manière par eux. Une des solutions classique consiste à vérifier les informations sur le navigateur utilisé par le client par l'attribut userAgent de l'objet navigator (navigator.userAgent), ce qui renvoie des informations comme: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36.

Une autre manière consiste à vérifier directement si le navigateur supporte une méthode ou un attribut sur un objet.

Exemple:
if(window.XMLHttpRequest)
   alert("XMLHttpRequest supporté.");
Dans ce cas, si window.XMLHttpRequest retourne true, cela signifie que la syntaxe ne génère pas d'erreur et que le navigateur la reconnait.
XMLHttpRequest est un objet Javascript utilisé en AJAX (Asynchronous Javascript And XML). On aura l'occasion de voir le cours d'AJAX plus loin.
Néanmoins, la méthode que je préfère pour gérer la compatibilité est la gestion des exceptions.

Exemple:
try{
   document.getElementById("id").filters.alpha.opacity=50;
}
catch(e){
   document.getElementById("id").style.opacity=0.5;
}
Ce code permet d'appliquer de la transparence à un objet HTML identifié par "id". Le bloc try contient la déclaration qui fonctionne sur les anciennes versions d'Internet Explorer, tandis que le bloc catch renferme la déclaration qui est censée fonctionner sur tous les autres navigateurs.

Lancement d'erreurs personnalisées: mot-clé throw

En Javascript, il est désormais possible de lancer ses propres erreurs de manière manuelle (on parle d'erreurs personnalisées). Le mot-clé throw permet de faire cette opération.

Le lancement d'exception personnalisée s'effectue généralement dans le bloc try. Une fois l'instruction throw rencontrée, le moteur Javascript sort immédiatement du bloc try courant et se branche au premier bloc catch suivant. Le mot-clé throw lance une instance de l'erreur Javascript nommée Error dont le constructeur accepte, comme argument , le message d'erreur voulu.

Imaginons que nous voulons créer un code qui est sensé générer un nombre aléatoire impair. Ce code ressemblera à ceci:
try{
   let a=Math.round(Math.random()*10);
   if (a%2==0)
      throw new Error("Nombre pair");
   console.log("Nombre impair");
}
catch(err){
   console.log(err);
}
Le code précédent génère un nombre entier aléatoire que l'on stocke dans la variable a. Dans le bloc try, on vérifie si le nombre est pair. Si c'est le cas, alors on lance une exception avec le message "Nombre pair" et on saute directement au bloc catch qui affiche le message à la console. Sinon, alors l’exécution du bloc try se poursuit et on aura à la console le message "Nombre impair". Dans ce dernier cas, le bloc catch ne s'exécutera pas.

Exécuter un traitement par défaut: mot-clé finally

Parfois, on est amené à exécuter un traitement quelque soit le sort du bloc try...catch, que l'on lance une exception personnalisée ou pas. Pour exécuter ce traitement (dit par défaut), on fait appel au mot clé finally.

Le mot-clé finally est souvent placé à la fin du bloc try...catch. A titre d'exemple, imaginons que l'on veut écrire du texte dans un DIV avec du Javascript. Or, nous ne savons pas si cette DIV existe déjà dans le document ou non. Dans ce cas, à l'aide du bloc try...catch on va essayer de vérifier l'existence de la div. Si elle n'existe pas on va la créer et, dans tout les cas, on va écrire le texte que voulons.

Le code peur ressembler à ceci:
try{
   const madiv=document.getElementById("madiv");
}
catch(err){
   const madiv=document.createElement("div");
   madiv.getAttribute("id","madiv");
   document.body.appendChild(madiv);
}
finally{
   madiv.innerHTML="Bonjour";
}
Dans ce cas, l'écriture du texte "Bonjour" a été effectuée dans le bloc finally et à ce stade, on est sûr que l'élément madiv est présent dans le document.