CodeGym /Cours /C# SELF /Catch multiple et filtres en C#

Catch multiple et filtres en C#

C# SELF
Niveau 13 , Leçon 4
Disponible

1. Introduction

Dès que ton programme devient un peu plus complexe que Hello, world!, tu te retrouves vite à devoir gérer différents types d’erreurs de façon différente. Imagine : tu bosses avec des fichiers, du réseau, une BDD — et pour chaque cas d’erreur, il faut réagir autrement. Par exemple, si un fichier manque, tu peux proposer à l’utilisateur d’en choisir un autre, et si c’est une erreur réseau — retenter l’opération ou afficher un message sympa genre "Vérifie le câble, peut-être que le chat l’a encore bouffé".

En C#, pour ça, on utilise plusieurs blocs catch à la suite. Chaque bloc est spécialisé sur son type d’exception (et ses enfants).

Structure d’un catch multiple


try
{
    // Ici — du code qui peut lancer différentes exceptions
}
catch (FileNotFoundException ex)
{
    Console.WriteLine($"Fichier non trouvé : {ex.Message}");
}
catch (IOException ex) // attrape toutes les erreurs d’entrée/sortie, sauf FileNotFoundException
{
    Console.WriteLine($"Erreur d’entrée-sortie : {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"Un truc s’est mal passé : {ex.Message}");
}
Blocs catch multiples pour différents types d’erreurs

Important ! Le compilateur parcourt les blocs de haut en bas et prend le premier qui correspond au type. Si un FileNotFoundException est attrapé, il ne va pas plus loin dans la chaîne.

Illustration de la "chaîne"

Type d’exception Quel bloc va l’attraper ?
FileNotFoundException Premier catch
IOException (autre) Deuxième catch
ArgumentException Troisième (général) catch

Pourquoi il ne faut pas tout mélanger ?
Le "piège" le plus large — genre catch (Exception) — mets-le toujours en dernier, sinon il va "gober" toutes les exceptions trop tôt, et les catch spécialisés ne seront jamais atteints.

C’est comme désactiver tous les détecteurs d’incendie d’un immeuble parce qu’un a réagi à un grille-pain cramé : les prochains incendies, le système ne les verra pas.

Exemple concret

using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            double result = CalculateAverageAgeFromFile("users.txt");
            Console.WriteLine($"Âge moyen — {result}");
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("Erreur : fichier non trouvé. Vérifie le chemin.");
        }
        catch (FormatException ex)
        {
            Console.WriteLine("Erreur de données : impossible de lire l’âge.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Autre erreur : {ex.Message}");
        }
    }

    static double CalculateAverageAgeFromFile(string filePath)
    {
        // (Implémentation : lit le fichier, parse les âges, calcule la moyenne)
        // ...
        throw new NotImplementedException();
    }
}

Ici, on sépare clairement quoi faire si le fichier n’existe pas (FileNotFoundException), et quoi faire si le fichier contient des données "foireuses" (FormatException). Tous les autres cas sont pris par le troisième bloc "de secours".

2. Filtres catch : attraper les subtilités

Les blocs catch multiples, c’est pratique, mais parfois ça ne suffit pas. Il arrive que, pour un même type d’exception, tu veuilles réagir différemment selon les circonstances.

Par exemple, si le réseau ne marche pas parce qu’il n’y a plus d’internet — on peut tenter de se reconnecter. Mais si c’est juste le serveur qui répond pas — peut-être qu’il faut afficher un autre message.

C’est là que les filtres catch entrent en jeu — une vraie super-feature de C# qui permet de filtrer non seulement par type, mais aussi par condition supplémentaire.

Syntaxe du filtre when


catch (IOException ex) when (ex.Message.Contains("pas de disque"))
{
    Console.WriteLine("Oups ! On dirait que tu as retiré la clé USB.");
}
catch (IOException ex)
{
    Console.WriteLine("Autre erreur d’entrée/sortie : " + ex.Message);
}
Filtre catch when pour préciser les conditions d’interception

Ici, le premier bloc attrape seulement les IOException dont le message contient la phrase "pas de disque" — tout le reste va dans le deuxième bloc.

Utilisation dans la vraie vie

Les filtres sont super utiles pour gérer les erreurs réseau, quand il faut décider quoi faire selon les propriétés internes de l’exception : retenter, ou juste afficher une erreur.

Encore un exemple : imagine, dans une méthode qui parse un fichier, tu veux pas juste un FormatException "générique", mais un cas à part si c’est l’âge qui pose problème (genre si l’âge est écrit "abc" au lieu d’un nombre).

catch (FormatException ex) when (ex.Message.Contains("âge"))
{
    Console.WriteLine("Erreur : impossible de lire l’âge. Vérifie les données.");
}
catch (FormatException ex)
{
    Console.WriteLine("Erreur de format des données : " + ex.Message);
}

Filtres et performance

Les filtres, c’est pratique, mais rappelle-toi que la condition du filtre est évaluée avant d’entrer dans le bloc catch, donc si elle n’est pas vraie — le corps du bloc n’est même pas exécuté.

D’ailleurs, si le filtre lui-même lance une exception (genre dans ton expression when tu fais une division par zéro) — cette exception ne sera jamais attrapée par ce bloc catch. Faut faire gaffe à ça.

3. Combiner plusieurs catch et des filtres

Imagine que dans ton projet tu dois gérer non seulement le type d’exception, mais aussi son état interne. Par exemple, avec une IOException, tu veux un comportement différent si c’est un problème d’accès ou si le disque est plein.


try
{
    File.AppendAllText("log.txt", "Nouvelle entrée\n");
}
catch (IOException ex) when (ex.Message.Contains("Plus d’espace"))
{
    Console.WriteLine("Erreur : Le disque est plein !");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Erreur : pas les droits pour écrire le fichier. Lance en tant qu’admin.");
}
catch (IOException ex)
{
    Console.WriteLine("Autre erreur disque : " + ex.Message);
}
Combinaison de filtres et de différents types de catch

Ici, on utilise à la fois un filtre et une séparation par type d’erreur. Cette flexibilité est super utile quand tu développes une appli complexe où il faut réagir de façon informative aux plantages fréquents.

4. Particularités et "pièges" des filtres et des catch multiples

  • Le filtre catch peut utiliser la variable d’exception (ex), mais ne peut pas la modifier.
  • Si tu lances une exception dans when, elle ne sera jamais "attrapée" par ce même catch — elle remonte la pile comme si le filtre n’existait pas.
  • La logique du filtre fait partie du contrat : ton collègue doit savoir que toutes les IOException ne seront pas attrapées — seulement si la condition est vraie.
  • Si tu utilises un seul catch pour toute la méthode, mais avec un filtre dedans, il y a un risque de rater des exceptions "en trop". Donc, si tu doutes — préfère des blocs séparés et explicites.
  • Dans les grosses applis, tu peux utiliser les filtres pour centraliser la logique, par exemple, ne logger que les erreurs critiques.

5. Scénarios pour les entretiens et le boulot réel

Connaître les filtres et les catch multiples, ce n’est pas juste pour faire joli ou avoir une bonne note en clean code. C’est une vraie compétence qu’on peut te demander en entretien, surtout si tu postules pour un poste où tu dois maintenir une grosse appli complexe et distribuée.

Exemples de questions :

  • Comment, en C#, gérer différents scénarios d’erreur de lecture de fichier, pour afficher un message différent selon la situation (pas de fichier, disque occupé, données corrompues) ?
  • Comment ne pas "étouffer" une erreur importante si tu mets un bloc général catch (Exception) ?
  • À quoi sert le filtre catch ? Est-ce qu’on peut mettre un throw dedans ?
1
Étude/Quiz
Découverte des exceptions, niveau 13, leçon 4
Indisponible
Découverte des exceptions
Stack d'appels et création de tes propres exceptions
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION