W3docs

Erreurs personnalisées en JavaScript

JavaScript permet de créer ses propres types d'erreurs en étendant la classe Error intégrée, pour une gestion plus précise et détaillée des erreurs.

Erreurs personnalisées en JavaScript

JavaScript vous permet de créer vos propres types d'erreurs en étendant la classe intégrée Error. Une erreur personnalisée est simplement une classe qui hérite de Error (ou d'un autre type d'erreur) et qui porte un name significatif ainsi que toute donnée supplémentaire requise par la situation.

Cette page explique pourquoi vous voudriez utiliser des erreurs personnalisées, comment les définir correctement, comment distinguer les types d'erreurs avec instanceof, comment attacher du contexte (codes de statut, noms de champs, le cause original), et comment organiser une hiérarchie d'erreurs pour une application réelle.

Pourquoi créer des erreurs personnalisées ?

Lancer un simple new Error("...") fonctionne, mais cela ne donne à l'appelant qu'une chaîne de caractères à inspecter. Les erreurs personnalisées résolvent trois problèmes :

  • Gestion basée sur le type. Avec instanceof ValidationError, vous pouvez réagir à un type d'échec précis sans analyser le texte du message, ce qui est fragile et dépendant de la locale.
  • Contexte supplémentaire. Une classe personnalisée peut transporter des champs structurés — un statusCode HTTP, le field concerné, une indication de nouvelle tentative — au lieu de tout entasser dans le message.
  • Hiérarchies claires. Une classe de base commune (par exemple AppError) permet à un gestionnaire de haut niveau d'intercepter toutes les erreurs de votre application en un seul instanceof, tout en laissant le code interne lancer des sous-types précis.

Si vous avez besoin d'apprendre d'abord les mécaniques de lancement/interception, lisez Gestion des erreurs : try...catch. Les erreurs personnalisées s'appuient directement sur l'héritage de classes et l'extension des classes intégrées.

Les bases de l'extension de la classe Error

Pour créer une erreur personnalisée, vous extend la classe Error. La nouvelle classe hérite de message, stack et toString() d'Error, et vous y ajoutez ce dont vous avez besoin.

Créer une classe d'erreur personnalisée

Voici le schéma minimal :

class ValidationError extends Error {
  constructor(message) {
    super(message);  // Pass the message to the Error constructor (sets this.message)
    this.name = "ValidationError";  // Override the default name "Error"
  }
}

Deux détails sont importants :

  • super(message) doit être appelé en premier. Dans un constructeur de sous-classe, vous ne pouvez pas utiliser this avant d'avoir appelé super(). Le constructeur d'Error définit this.message et capture la trace de la pile d'appels.
  • Définissez this.name. Sans cela, l'erreur apparaît comme "Error" dans les messages et dans toString(). Définir name rend les journaux et le motif switch (error.name) lisibles.

Vous pouvez également voir Object.setPrototypeOf(this, new.target.prototype) dans certains exemples. Avec les transpileurs modernes et les classes natives, c'est généralement inutile, mais cela ne nuit pas et garantit que instanceof fonctionne même lorsque le code est compilé vers ES5 ou partagé entre des contextes différents (iframes/workers). Les exemples ci-dessous le conservent par sécurité.

Une fois créée, l'erreur se comporte comme n'importe quelle autre :

const e = new ValidationError("bad input");
e.name;               // "ValidationError"
e instanceof Error;   // true  — it is still a real Error
e.toString();         // "ValidationError: bad input"

Utiliser des erreurs personnalisées

Une fois que vous avez défini une erreur personnalisée, vous pouvez la lancer dans votre application comme n'importe quelle erreur standard :

javascript— editable

Dans cet exemple, un e-mail est validé par rapport à une expression régulière. Si la validation échoue, une ValidationError est lancée. Cette erreur est ensuite interceptée dans le bloc try...catch, et si elle est une instance de ValidationError, un message spécifique est affiché dans la console.

Gérer plusieurs types d'erreurs personnalisées

Vous pourriez vouloir créer différents types d'erreurs pour différentes parties de votre application. Voici comment gérer plusieurs erreurs personnalisées :

javascript— editable

Cette organisation permet une gestion distincte des différents types d'erreurs, rendant l'application plus robuste et plus facile à déboguer.

Préférez instanceof à la comparaison de chaînes error.name quand vous le pouvez : instanceof correspond également aux sous-classes, donc il résiste mieux au refactoring.

Construire une hiérarchie d'erreurs avec une classe de base

Dans les applications réelles, il est utile de donner à toutes vos erreurs un ancêtre commun. Un gestionnaire de haut niveau peut alors intercepter chaque erreur « attendue » de l'application en un seul endroit, tout en laissant le code plus profond lancer des sous-types précis. L'option cause (ES2022) permet à une erreur de haut niveau d'encapsuler l'erreur de bas niveau qui l'a déclenchée, préservant l'originale pour le débogage.

javascript— editable

Ici, this.name = this.constructor.name évite de devoir répéter le nom dans chaque sous-classe, et le seul contrôle instanceof AppError capture NotFoundError, ConflictError, et tout futur sous-type.

Gestion avancée des erreurs personnalisées en JavaScript

En s'appuyant sur les bases, nous pouvons appliquer les erreurs personnalisées à des scénarios plus complexes comme les opérations asynchrones et les cas spécifiques à la logique métier.

Exemple 1 : Gestion des erreurs API personnalisées

Cet exemple montre comment créer et utiliser une erreur personnalisée pour gérer les problèmes de requêtes API, comme lorsqu'une ressource demandée est introuvable ou que le serveur renvoie une erreur. Le flux async/await présenté ici s'associe à la gestion des erreurs avec les promesses.

javascript— editable

Explication

  • Classe ApiError : Cette classe personnalisée capture les erreurs spécifiques aux API, en stockant le code de statut HTTP avec un message personnalisé.
  • Fonction fetchData : Tente de récupérer des données depuis une URL fournie. Si la réponse n'est pas réussie, elle lance une ApiError avec un message détaillé et le code de statut.
  • Gestion des erreurs : Les erreurs sont interceptées et traitées de manière appropriée. Les erreurs liées aux API sont journalisées avec des informations détaillées, tandis que les erreurs inattendues sont également interceptées et journalisées.

Exemple 2 : Gestion des erreurs de validation personnalisées

Utilisez cet exemple pour gérer les erreurs liées à la validation des données, comme la vérification des entrées utilisateur.

javascript— editable

Explication

  • Classe ValidationError : Une classe d'erreur personnalisée qui aide à identifier quel champ spécifique des données d'entrée a échoué à la vérification de validation.
  • Fonction validateUser : Vérifie la validité des données utilisateur. Si les données ne satisfont pas certains critères, elle lance une ValidationError.
  • Gestion des erreurs : Intercepte les erreurs de validation et les journalise avec des informations détaillées. Les autres types d'erreurs sont également gérés séparément.

Bonnes pratiques et pièges à éviter

  • Appelez toujours super(message) en premier, avant de toucher à this.
  • Définissez name pour que les journaux et toString() soient lisibles ; this.name = this.constructor.name le fait une seule fois pour toute une hiérarchie.
  • Préférez instanceof aux comparaisons error.name — il correspond également aux sous-classes.
  • Relancez ce que vous ne reconnaissez pas. Un catch qui avale tout (catch (e) {}) masque de vrais bogues. Gérez vos types connus et faites throw error pour le reste, comme le font les exemples.
  • Utilisez cause pour encapsuler, pas pour remplacer. Quand vous interceptez une erreur de bas niveau et lancez une erreur de haut niveau, passez { cause: original } pour que la trace de pile et la cause racine soient préservées.
  • Ne sous-classez pas Error pour contrôler le flux. Les erreurs sont faites pour les conditions exceptionnelles, pas pour les branchements normaux.

Conclusion

Créer des classes d'erreurs personnalisées en JavaScript en étendant la classe Error est une technique puissante pour gérer des types d'erreurs spécifiques de manière plus granulaire. Elle améliore la clarté et la maintenabilité de la gestion des erreurs dans votre code, vous permettant de fournir des retours et des actions plus précis selon les différentes conditions d'erreur. Cette méthode aide non seulement au débogage, mais améliore également la fiabilité de vos applications en garantissant que chaque type d'erreur est intercepté et traité de manière appropriée.

Pratique

Pratique
Quel est l'objectif de l'utilisation de classes d'erreurs étendues en JavaScript ?
Quel est l'objectif de l'utilisation de classes d'erreurs étendues en JavaScript ?
Pratique
Dans un constructeur de sous-classe d'erreur personnalisée, pourquoi super(message) doit-il être appelé avant d'utiliser this ?
Dans un constructeur de sous-classe d'erreur personnalisée, pourquoi super(message) doit-il être appelé avant d'utiliser this ?
Pratique
Que permet l'option cause d'ES2022 lors du lancement d'une erreur personnalisée ?
Que permet l'option cause d'ES2022 lors du lancement d'une erreur personnalisée ?
Was this page helpful?