Attraper en une fois : comment intercepter plusieurs exceptions en C# sans dupliquer le code
\n\nImaginez : vous développez une application qui manipule des fichiers, le réseau et des bases de données. Dans une même méthode, vous pouvez rencontrer FileNotFoundException, IOException ou UnauthorizedAccessException. L'approche classique consiste à écrire trois blocs catch avec le même code à l'intérieur. Cela viole le principe DRY (Don't Repeat Yourself) et transforme votre code en "spaghetti".
Bonne nouvelle : en C#, il existe plusieurs façons élégantes d'intercepter plusieurs exceptions à la fois. Dans ce tutoriel, nous allons explorer toutes les options — des plus basiques aux plus avancées — et vous apprendrez à écrire un code de gestion d'erreurs propre et maintenable.
\n\nPourquoi est-ce important ? Un scénario concret
\n\nSupposons que vous développiez une application console pour la sauvegarde de données. Elle lit des fichiers, les compresse et les envoie vers un serveur distant. À chaque étape, différentes exceptions peuvent survenir :
\n\n- \n
- Lecture du fichier :
FileNotFoundException,PathTooLongException\n - Compression :
OutOfMemoryException\n - Envoi :
HttpRequestException,TimeoutException\n
Si vous écrivez un bloc catch séparé pour chaque exception avec la même journalisation, le code deviendra lourd. Et si vous devez modifier la logique plus tard, vous devrez corriger à trois endroits. C'est là que savoir attraper plusieurs exceptions en une fois devient indispensable.
Méthode 1. Classique : plusieurs blocs catch (avant C# 6)
\n\nLa méthode la plus simple et évidente consiste à écrire plusieurs blocs catch à la suite. C# sélectionne automatiquement le bloc approprié en fonction du type d'exception :
try\n{\n // Code pouvant lever différentes exceptions\n string content = File.ReadAllText(@"C:\\data\\config.txt");\n int value = int.Parse(content);\n await SendToServerAsync(value);\n}\ncatch (FileNotFoundException ex)\n{\n Console.WriteLine($"Fichier introuvable : {ex.Message}");\n LogError(ex);\n}\ncatch (FormatException ex)\n{\n Console.WriteLine($"Format de données invalide : {ex.Message}");\n LogError(ex);\n}\ncatch (HttpRequestException ex)\n{\n Console.WriteLine($"Erreur réseau : {ex.Message}");\n LogError(ex);\n}\n\nAvantages : clair, facile à lire, permet de traiter chaque exception différemment.
\nInconvénients : si les actions sont identiques, cela entraîne une duplication de code.
Méthode 2. Intercepter plusieurs exceptions dans un seul catch (C# 6+)
\n\nDepuis C# 6, vous pouvez lister plusieurs types d'exceptions avec | dans un seul bloc catch. Cela réduit la duplication tout en restant lisible :
try\n{\n // Code risqué\n}\ncatch (FileNotFoundException | FormatException | HttpRequestException ex)\n{\n Console.WriteLine($"Une erreur est survenue : {ex.Message}");\n LogError(ex);\n // Logique supplémentaire commune aux trois types\n}\n\nImportant : toutes les exceptions doivent être compatibles hiérarchiquement. On ne peut pas mélanger, par exemple, IOException et NullReferenceException — elles n'ont pas d'ancêtre commun autre que Exception. Mais en C# 6+, c'est autorisé ; le compilateur convertit simplement la variable ex vers le type de base commun.
Quand utiliser cette méthode ?
\n- \n
- Lorsque la logique de traitement est identique pour toutes les exceptions. \n
- Pour éviter les blocs
ifouswitchimbriqués. \n - Dans les petites méthodes où la concision est importante. \n
Méthode 3. Filtres d'exceptions (C# 6+)
\n\nLes filtres d'exceptions sont un mécanisme puissant qui permet d'attraper des exceptions selon une condition, grâce au mot-clé when. Vous pouvez intercepter la même exception mais avec une logique différente selon ses propriétés :
try\n{