Les types d'erreurs
Distinguer erreur de syntaxe, erreur à l’exécution et erreur logique.
Objectifs
À la fin de cette leçon, vous saurez :
- classer toute panne en trois familles : syntaxe, exécution, logique ;
- associer à chaque famille son moment de détection et sa méthode de recherche ;
- lire un message d'erreur comme une information, pas comme un échec ;
- reconnaître les messages d'exécution les plus courants de JavaScript.
Pourquoi classer ?
« Ça ne marche pas » n'aide jamais — ni vous, ni celui qui veut vous aider. Nommer la famille du problème oriente directement la méthode de recherche :
| Famille | Détectée quand | Symptôme visible |
|---|---|---|
| Erreur de syntaxe | avant l'exécution | le programme refuse de démarrer |
| Erreur à l'exécution | pendant l'exécution | il démarre... puis plante en route |
| Erreur logique | par l'humain seulement | aucun crash, mais résultat faux |
Ce classement n'est pas scolaire : il dicte où chercher. Une erreur de syntaxe se règle dans l'éditeur ; une erreur d'exécution se règle en suivant la stack trace ; une erreur logique exige des résultats attendus et une vérification. Trois familles, trois méthodes.
Erreur de syntaxe : le code viole la grammaire
$ node test.js
const total = (4 + 5 * 2;
^
SyntaxError: missing ) after argument list
Caractéristiques essentielles :
- aucune ligne du fichier ne s'exécute : Node refuse de lire l'ensemble tant que la grammaire est violée ;
- le message indique presque toujours la position exacte (
fichier:ligne, et le petit^pointe la colonne) ; - causes fréquentes : parenthèse/accolade/guillemet non fermés, virgule manquante dans un objet ou un tableau,
=écrit au lieu de:dans un objet.
Bonne nouvelle : c'est la famille la plus facile — la machine vous dit quoi et où. Mauvaise habitude à éviter : paniquer et tout réécrire. Lisez la position, regardez la ligne, corrigez le délimiteur fautif.
Erreur à l'exécution : la grammaire passe, la réalité non
Le code est grammaticalement parfait ; le programme démarre, puis rencontre quelque chose d'impossible :
const notes = null;
console.log(notes.length);
$ node test.js
console.log(notes.length);
^
TypeError: Cannot read properties of null (reading 'length')
Notez ce qui s'est passé : la première ligne a bien été exécutée, puis le programme s'est arrêté net sur la seconde. Les erreurs d'exécution courantes en JavaScript, à connaître comme son alphabet :
| Message | Cause typique | Traduction humaine |
|---|---|---|
ReferenceError: x is not defined | nom mal orthographié ou jamais déclaré | « je ne connais pas ce mot » |
TypeError: Cannot read properties of undefined/null | accès à une propriété d'un objet inexistant | « je cherche une pièce dans une maison vide » |
TypeError: x is not a function | appel de quelque chose qui n'est pas une fonction | « je demande à un caillou de faire cuire » |
RangeError: Invalid array length | taille de tableau invalide (négative, trop grande) | « cette taille n'a pas de sens » |
Exemple concret du plus fréquent — la faute de frappe :
let message = "salut";
console.log(mesage); // un « s » manquant...
// ReferenceError: mesage is not defined
Ces erreurs arrêtent le programme : tout ce qui devait suivre n'a pas eu lieu. C'est brutal mais honnête — et la prochaine leçon vous apprendra à exploiter la stack trace qu'elles laissent derrière elles.
Erreur logique : le pire des trois
Rien ne plante. Le programme tourne, affiche fièrement ses résultats... et ils sont faux :
function moyenne(notes) {
let total = 0;
for (const note of notes) {
total += note;
}
return total / (notes.length - 1); // bug silencieux !
}
console.log(moyenne([12, 14, 16])); // 21 : aucun crash… et pourtant
La moyenne de 12, 14 et 16 est 14 — pas 21. Aucun outil automatique ne peut savoir que vous vouliez diviser par notes.length plutôt que notes.length - 1 : pour la machine, le programme fait exactement ce que son texte dit. C'est pourquoi cette famille est la plus coûteuse : seule la comparaison avec un résultat attendu la révèle.
C'est précisément pour cela que tous les exercices de ce cours vous font prédire les sorties avant d'exécuter : sans attendu, pas d'erreur logique détectable. Un développeur qui ne sait pas ce que son code devrait produire ne peut pas savoir qu'il produit autre chose.
Trois sources classiques d'erreurs logiques, à surveiller dès maintenant :
- conditions aux bornes :
>au lieu de>=(« majeur » = 18 ans inclus ?) ; - boucles off-by-one :
<=au lieu de<(visiter un index de trop — vous en verrez en exercice) ; - mauvais opérateur :
+là où il fallait concaténer ou inversement.
Et demain ? Les autres familles du cursus
Pour situer le paysage complet — ces familles seront traitées là où elles vivent vraiment :
- erreur réseau (chapitre 8) : la machine joignable hier ne répond plus ;
- erreur HTTP (chapitre 11) : le serveur répond, mais pas ce qu'on attendait (404 : ressource absente ; 500 : son propre plantage) ;
- erreur SQL (chapitre 20) : requête invalide, contrainte violée.
Même mécanisme mental dans tous les cas : identifier la famille, lire le message jusqu'au bout, localiser, comprendre avant de modifier.
Exercice
Classez chaque situation (syntaxe / exécution / logique) et justifiez en une demi-phrase :
console.log("bonjour"— parenthèse jamais fermée.- Une fonction renvoie toujours
false, même quand elle devrait renvoyertrue. let x = valeurInconnue;oùvaleurInconnuen'existe nulle part.- Le programme affiche une liste triée décroissante alors qu'on voulait croissante.
const liste = [{nom:"a"}]; console.log(liste[1].nom);totalPanier([10, 20, 30])afficheNaNau lieu de60.- Un serveur répond
404à votre requête.
Résumé
- Syntaxe : refus de démarrer, position signalée — corriger le délimiteur indiqué.
- Exécution : démarre puis plante ; type + message + stack trace sont vos alliés.
- Logique : silencieuse ; seul un résultat attendu la révèle.
- Réflexe professionnel unique face aux trois : lire le message jusqu'au bout AVANT de toucher au code.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
1. Syntaxe. La grammaire est incomplète ; Node signale la parenthèse manquante avant d'exécuter quoi que ce soit.
2. Logique. Aucune exception : seul l'écart entre résultat obtenu et résultat voulu trahit le bug (condition inversée, opérateur erroné).
3. Exécution (ReferenceError). Syntaxe parfaite ; le plantage survient au moment où la ligne s'exécute et cherche un nom introuvable.
4. Logique. Le tri fonctionne (pas de plantage), le sens est inversé : probablement > au lieu de < dans la comparaison. Seul un résultat attendu permettait de le voir.
5. Exécution (TypeError). liste[1] vaut undefined (le tableau n'a qu'un élément), et lire .nom sur undefined est impossible — « chercher une pièce dans une maison vide ».
6. Logique — avec une subtilité instructive. NaN ne provoque aucun crash : c'est le résultat mathématiquement « valide » d'un calcul cassé (typiquement : additionner un élément hors limites, undefined + 10). La machine a calculé ; c'est le calcul qui est faux.
7. HTTP — famille à venir (chapitre 11). Nuance importante : le programme ne plante pas forcément ; le serveur a répondu, simplement « cette ressource n'existe pas ». C'est au code client de vérifier le statut reçu — négliger cette vérification transformera alors l'erreur HTTP en erreur logique (traiter une réponse d'erreur comme une donnée).