Aller au contenu principal

Module JS.9 – Erreurs

Objectif

Maîtriser la gestion des erreurs JavaScript : try/catch, gestion des erreurs asynchrones, et création d'erreurs personnalisées pour créer des applications robustes.

Théorie

try/catch/finally

Structure de base pour gérer les erreurs.

try {
// Code qui peut générer une erreur
const resultat = operationRisquee();
} catch (erreur) {
// Gestion de l'erreur
console.error("Erreur :", erreur.message);
} finally {
// Code toujours exécuté
console.log("Nettoyage");
}

Propriétés de l'erreur :

catch (erreur) {
erreur.name; // Type d'erreur
erreur.message; // Message d'erreur
erreur.stack; // Pile d'appels
}

Types d'erreurs

Error : Erreur générique

throw new Error("Message d'erreur");

Types spécifiques :

throw new TypeError("Type incorrect");
throw new ReferenceError("Variable non définie");
throw new SyntaxError("Erreur de syntaxe");
throw new RangeError("Valeur hors limites");

Créer des erreurs personnalisées :

class ValidationError extends Error {
constructor(message, champ) {
super(message);
this.name = "ValidationError";
this.champ = champ;
}
}

throw new ValidationError("Email invalide", "email");

Gestion des erreurs asynchrones

Avec Promises

maPromise
.then((resultat) => {
// Succès
})
.catch((erreur) => {
// Erreur
console.error(erreur);
});

Avec async/await

async function operation() {
try {
const resultat = await maPromise;
return resultat;
} catch (erreur) {
console.error("Erreur :", erreur);
throw erreur; // Re-lancer l'erreur si nécessaire
}
}

Gestion globale :

window.addEventListener('unhandledrejection', (event) => {
console.error('Promise non gérée :', event.reason);
event.preventDefault(); // Empêche l'erreur dans la console
});

Bonnes pratiques

1. Toujours gérer les erreurs

// ❌ Mauvais
async function charger() {
const data = await fetch('/api/data');
return data.json();
}

// ✅ Bon
async function charger() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (erreur) {
console.error("Erreur de chargement :", erreur);
throw erreur; // Ou retourner une valeur par défaut
}
}

2. Messages d'erreur clairs

// ❌ Mauvais
throw new Error("Erreur");

// ✅ Bon
throw new ValidationError("L'email doit être valide", "email");

3. Logging approprié

catch (erreur) {
// Log pour le développeur
console.error("Erreur technique :", erreur);

// Message utilisateur clair
afficherMessage("Une erreur s'est produite. Veuillez réessayer.");
}

4. Ne pas exposer les détails

// ❌ En production
catch (erreur) {
alert(erreur.stack); // Expose trop d'infos
}

// ✅ En production
catch (erreur) {
console.error(erreur); // Log pour développeur
alert("Une erreur s'est produite"); // Message générique
}

Validation et erreurs personnalisées

class ValidationError extends Error {
constructor(message, champ) {
super(message);
this.name = "ValidationError";
this.champ = champ;
}
}

function validerEmail(email) {
if (!email) {
throw new ValidationError("Email requis", "email");
}
if (!email.includes("@")) {
throw new ValidationError("Email invalide", "email");
}
return true;
}

try {
validerEmail("");
} catch (erreur) {
if (erreur instanceof ValidationError) {
console.error(`Erreur de validation (${erreur.champ}) : ${erreur.message}`);
} else {
console.error("Erreur inattendue :", erreur);
}
}

Gestion d'erreurs dans les boucles

const donnees = [1, 2, 3, "erreur", 5];

// Continue malgré les erreurs
for (const item of donnees) {
try {
const resultat = operationRisquee(item);
console.log(resultat);
} catch (erreur) {
console.error(`Erreur pour ${item} :`, erreur.message);
// Continue avec le suivant
}
}

Assertions

function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion échouée");
}
}

function diviser(a, b) {
assert(b !== 0, "Division par zéro impossible");
return a / b;
}

Exercice

  1. try/catch

    • Créez du code qui génère des erreurs
    • Capturez-les avec try/catch
    • Affichez les propriétés des erreurs
  2. Erreurs personnalisées

    • Créez des classes d'erreur personnalisées
    • Lancez-les dans votre code
    • Gérez-les spécifiquement
  3. Erreurs asynchrones

    • Gèrez les erreurs dans des Promises
    • Utilisez try/catch avec async/await
    • Testez les erreurs non gérées
  4. Validation

    • Créez un système de validation
    • Lancez des erreurs personnalisées
    • Gérez-les gracieusement
  5. Bonnes pratiques

    • Appliquez les bonnes pratiques
    • Loggez correctement
    • Masquez les détails en production

Quiz

  1. Que fait finally ?

    • Gère les erreurs
    • S'exécute toujours
    • Annule l'erreur
  2. Comment créer une erreur personnalisée ?

    • new Error("message")
    • Créer une classe qui étend Error
    • throw "message"
  3. Comment gérer les erreurs avec async/await ?

    • .catch()
    • try/catch
    • .then()
  4. Que fait instanceof avec les erreurs ?

    • Vérifie le type
    • Vérifie le type d'erreur
    • Lance une erreur
  5. Pourquoi ne pas exposer les détails d'erreur en production ?

    • Pour améliorer les performances
    • Pour la sécurité et l'expérience utilisateur
    • Pour réduire la taille du code

Mini défi

Mission : Créer un système de gestion d'erreurs robuste

Créez un système complet de validation avec gestion d'erreurs :

Fonctionnalités :

  1. Erreurs personnalisées

    • ValidationError : Erreurs de validation
    • FormatError : Format incorrect
    • RequiredError : Champ requis manquant
  2. Fonctions de validation

    • validerEmail(email) : Valide un email
    • validerAge(age) : Valide un âge (13-120)
    • validerMotDePasse(mdp) : Valide un mot de passe (8+ caractères)
    • validerTelephone(tel) : Valide un numéro de téléphone
  3. Fonction de validation complète

    • validerFormulaire(donnees) : Valide tous les champs
    • Lance les erreurs appropriées
    • Collecte toutes les erreurs
  4. Gestion des erreurs

    • Affiche les erreurs par champ
    • Log les erreurs pour le développeur
    • Message utilisateur clair
  5. Gestion asynchrone

    • validerAsync(donnees) : Validation asynchrone
    • Gère les erreurs avec async/await
    • Retourne les résultats formatés

Exemple d'utilisation :

const donnees = {
email: "email-invalide",
age: 5,
mot_de_passe: "123"
};

try {
validerFormulaire(donnees);
} catch (erreur) {
if (erreur instanceof ValidationError) {
console.error(`Erreur ${erreur.champ} : ${erreur.message}`);
}
}

Critères :

  • ✅ Erreurs personnalisées créées
  • ✅ Toutes les validations implémentées
  • ✅ Gestion d'erreurs complète
  • ✅ Messages clairs pour l'utilisateur
  • ✅ Logging pour le développeur
  • ✅ Code robuste et sécurisé

Objectif : Maîtriser la gestion des erreurs JavaScript et créer un système robuste avec erreurs personnalisées.


Validation : Vous pouvez passer au module suivant quand vous maîtrisez try/catch, erreurs personnalisées et pouvez créer un système de gestion d'erreurs complet.