throw en JavaScript : lever une erreur volontairement

throw lève une erreur volontairement et interrompt le fil d'exécution jusqu'au premier bloc catch : c'est la façon de refuser une donnée invalide.
3 min de lecture
Believemy logo

Une fonction qui reçoit une donnée qu'elle ne sait pas traiter a deux choix : renvoyer une valeur bancale et laisser le problème se propager, ou refuser franchement. throw est le mot-clé du refus franc.

Bien employé, il transforme une panne lointaine et incompréhensible en un message précis, levé à l'endroit exact où la donnée est entrée dans le programme.


Définition

throw lève une erreur. La fonction courante s'arrête immédiatement, et le moteur remonte la pile d'appels à la recherche du premier catch disponible. S'il n'en trouve aucun, l'erreur s'affiche dans la console et le processus s'arrête.

JAVASCRIPT
function diviser(a, b) {
  if (b === 0) {
    throw new Error("Division par zéro");
  }
  return a / b;
}

try {
  diviser(10, 0);
} catch (erreur) {
  console.log(erreur.name, ":", erreur.message);
  // Error : Division par zéro
}

Notez le new devant Error : on ne lève pas un message, on lève un objet construit pour l'occasion.


Lever un objet Error, jamais une chaîne

Le langage accepte n'importe quelle valeur : un nombre, une chaîne, un objet quelconque. Une liberté qui coûte cher, et le tableau suivant explique pourquoi.

Ce qui est levéCe que le bloc de rattrapage obtient
Une chaîneAucune pile d'appels, aucun type, un message nu
Un objet ordinaireDes propriétés utiles, mais toujours aucune pile
Une instance de ErrorType, message, pile d'appels et cause éventuelle

La pile d'appels est la partie irremplaçable : c'est elle qui indique la ligne fautive et le chemin parcouru pour y arriver.


Ses propres types d'erreur

Dès qu'une application distingue plusieurs familles de problèmes, il devient utile de créer ses propres types en héritant de Error. Le rattrapage peut alors trier avec instanceof au lieu de comparer des messages, qui changent au premier remaniement.

JAVASCRIPT
class ErreurDePaiement extends Error {
  constructor(message, code) {
    super(message);
    this.name = "ErreurDePaiement";
    this.code = code;
  }
}

try {
  throw new ErreurDePaiement("Carte refusée", "card_declined");
} catch (erreur) {
  console.log(erreur instanceof Error);   // true
  console.log(erreur.name, erreur.code);  // ErreurDePaiement card_declined
}

La construction repose sur class, extends et super, trois mots-clés qui suffisent à obtenir un type d'erreur complet. L'appel à super(message) est obligatoire : c'est lui qui renseigne le message et capture la pile.

Bon à savoir

Pour relancer une erreur en ajoutant du contexte sans perdre l'originale, passez-la en cause : throw new Error("Configuration illisible", { cause: erreur }). Le bloc du dessus retrouve la première erreur dans erreur.cause.


Questions fréquentes

Question

Où faut-il lever, et où faut-il rattraper ?

Levez au plus près de la donnée fautive, là où le programme dispose du contexte pour dire ce qui ne va pas. Rattrapez au plus près de l'utilisateur, là où une décision est possible : afficher un message, réessayer, revenir à une valeur de repli.


Question

Une erreur levée arrête-t-elle tout le programme ?

Non, elle arrête le fil d'exécution en cours jusqu'au premier bloc capable de la recevoir. Dans un navigateur, une erreur non rattrapée interrompt le gestionnaire d'événement concerné mais la page reste vivante. Dans Node.js, elle met fin au processus, ce qui explique pourquoi les serveurs entourent chaque requête d'un rattrapage.


Question

Vaut-il mieux lever une erreur ou renvoyer null ?

Renvoyer null convient quand l'absence est un résultat normal, comme une recherche qui ne trouve rien. Levez une erreur quand la situation est anormale et qu'aucun appelant raisonnable ne peut continuer, comme une clé d'API manquante. Le critère n'est pas la gravité mais la question suivante : est-ce que l'appelant a quelque chose de sensé à faire de cette valeur.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.