CodeGym /Cours /C# SELF /Syntaxe try-catch : gestion des erreurs

Syntaxe try-catch : gestion des erreurs

C# SELF
Niveau 13, Leçon 1
Disponible

1. Introduction

Dans un monde idéal, le code serait parfait. Mais, malheureusement, même le dev le plus soigneux va un jour tomber sur des situations inattendues : fichier introuvable, l’utilisateur tape une chaîne au lieu d’un nombre, le réseau s’arrête d’un coup, ou la base de données renvoie un truc chelou.

Si tu ne gères pas ces problèmes — le programme va juste "planter", parfois avec un message d’erreur mystérieux et un stack trace (pile d’appels). C’est pas ce qu’attend l’utilisateur ni le futur support technique. Il faut apprendre à "attraper" ces erreurs et réagir : terminer proprement, afficher un message humain ou même corriger la situation à la volée.

try-catch — c’est la façon de dire au compilateur et au runtime : "Essaye d’exécuter ce bout de code. S’il y a un souci, panique pas, laisse-moi gérer !"

2. Syntaxe de base try-catch

La structure générale est super simple :


try
{
    // Ici on écrit du code risqué (ou potentiellement risqué)
}
catch (ExceptionType variableName)
{
    // Ici on écrit quoi faire si une exception de type ExceptionType apparaît
}
Syntaxe de base try-catch
  • Le bloc try — c’est la "zone à risque". On y met les opérations qui peuvent potentiellement "exploser".
  • Le bloc catch — attrape les exceptions d’un certain type. Si une exception apparaît dans try, le contrôle saute direct au premier catch qui correspond, et le code après l’endroit "problématique" dans try ne sera pas exécuté.

Exemple : gestion simple d’une exception

Imaginons que notre mini-calculatrice des leçons précédentes sait maintenant diviser des nombres. Mais l’utilisateur peut entrer zéro ! Voyons ce qui se passe sans gestion d’erreur :

int a = 10;
int b = 0;
int result = a / b; // BOUM ! System.DivideByZeroException
Console.WriteLine(result);

Le programme va s’arrêter brutalement avec l’erreur DivideByZeroException :

Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.

Maintenant, "réparons" ça avec try-catch :

int a = 10;
int b = 0;

try
{
    int result = a / b; // opération risquée
    Console.WriteLine("Résultat de la division : " + result);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("Oups ! Division par zéro impossible : " + ex.Message);
}

Maintenant le programme ne va pas "planter". La console affichera un message sur l’impossibilité de diviser par zéro :

Oups ! Division par zéro impossible : Attempted to divide by zero.

3. Comment fonctionne try-catch : étape par étape

En vrai, tu peux mettre autant de lignes de code que tu veux dans try. Si une action dans le bloc lance une exception, le contrôle saute direct au catch le plus proche qui correspond. Tout ce qui est écrit après l’erreur dans le bloc try ne sera pas exécuté.

Regardons un exemple un peu plus costaud :

try
{
    Console.WriteLine("On commence...");
    int[] numbers = { 1, 2, 3 };
    Console.WriteLine(numbers[1]);    // ça passe
    Console.WriteLine(numbers[5]);    // erreur : index hors du tableau
    Console.WriteLine("Ce message n’apparaîtra jamais !");
}
catch (IndexOutOfRangeException)
{
    Console.WriteLine("Erreur : tentative d’accès à un élément inexistant du tableau");
}

La sortie console sera :

On commence...
2
Erreur : tentative d’accès à un élément inexistant du tableau

Process finished with exit code 0.

Comment marche ce programme ?

  • Il affiche "On commence...".
  • Puis il essaie d’afficher l’élément numbers[1] — c’est 2.
  • Quand il arrive à numbers[5], ça "crashe" et ça lance IndexOutOfRangeException.
  • Le programme saute direct dans le bloc catch, en zappant Console.WriteLine("Ce message n’apparaîtra jamais !");
  • La console affiche notre message du catch.

4. Peut-on gérer différents types d’erreurs différemment ?

Oui ! Tu peux mettre plusieurs blocs catch pour réagir différemment selon le type d’exception. C’est pratique : par exemple, si une action concerne la lecture d’un fichier (ça peut lancer FileNotFoundException), et une autre — une division (ça peut lancer DivideByZeroException).

try
{
    // Ton code risqué
}
catch (DivideByZeroException)
{
    Console.WriteLine("Erreur de division par zéro");
}
catch (IndexOutOfRangeException)
{
    Console.WriteLine("Erreur : index hors du tableau");
}
catch (Exception ex)
{
    Console.WriteLine("Une erreur imprévue : " + ex.Message);
}

Ici, le dernier bloc catch avec le type Exception — c’est le "filet universel". Il attrapera toutes les autres exceptions qui n’ont pas été gérées avant. Mais attention : si tu le mets en premier, les autres ne seront jamais atteints ! Mets toujours les catch "larges" à la fin.

5. À quoi ressemble un objet exception ?

Dans le bloc catch, tu peux optionnellement mettre une variable — genre catch (Exception ex). Elle contient toutes les infos sur l’erreur : message, type, stack trace, exceptions imbriquées.

Petit exemple :

try
{
    string? text = null;
    Console.WriteLine(text.Length); // Oups ! NullReferenceException
}
catch (NullReferenceException ex)
{
    Console.WriteLine("Exception attrapée : " + ex.Message);
    Console.WriteLine("Stack trace : " + ex.StackTrace);
}

Cette approche sauve la vie quand tu débogues des bugs tordus : tu peux toujours voir où et pourquoi ton programme a "trébuché".

6. Attraper une erreur et continuer

Dans les vraies applis, surtout côté utilisateur, une erreur — c’est pas la fin du monde. Si la personne tape un mauvais chemin de fichier, ça arrive. C’est pas une raison pour faire planter le programme. À la place, on lui demande juste de réessayer.

L’exemple ci-dessous montre une approche simple mais efficace : on met la lecture du fichier dans une boucle, et si ça foire, on affiche un message d’erreur et on redemande. Pas de panique, pas d’écran rouge.

bool success = false;
while (!success)
{
    Console.Write("Tape le nom du fichier : ");
    string fileName = Console.ReadLine() ?? "";

    try
    {
        string content = File.ReadAllText(fileName);
        Console.WriteLine("Fichier lu avec succès !");
        success = true; // YES !
    }
    catch (FileNotFoundException)
    {
        Console.WriteLine("Erreur : fichier introuvable. Essaie encore.");
    }
}

L’idée clé ici — c’est pas juste d’attraper l’exception, mais de bien la gérer : on ne laisse pas le programme planter, on le met en mode "vas-y, recommence mais bien". L’utilisateur a une explication claire, le programme a une seconde chance, et toi — tu gagnes du respect.

7. Erreurs classiques avec try-catch

Erreur n°1 : Tout mettre dans un seul gros try-catch universel.
Ça a l’air tentant — un try, un catch (Exception), et hop, "tout est protégé". Mais en vrai, tu perds le contrôle. Tu sais pas où ça a planté, ni à quelle erreur tu réagis vraiment. Résultat : au lieu de la fiabilité, tu perds toute la capacité de diagnostiquer.

Erreur n°2 : Attraper des exceptions et ne rien en faire.
Exemple de la vraie vie :

try
{
    // un truc potentiellement risqué
}
catch
{
    // silence radio...
}
Ce code dit littéralement : "Y a eu un souci... tant pis". C’est dangereux : le programme peut continuer dans un état foireux, et tu ne sauras même pas qu’il y a eu une erreur. Affiche au moins un message ou loggue le bug. Jamais de catch vide !

Erreur n°3 : Attraper un type d’exception trop général.
Si tu attrapes Exception, alors que tu sais que ça peut être, par exemple, FormatException ou FileNotFoundException, — tu te prives de la possibilité de réagir correctement au vrai problème. Plus ton catch est précis, plus ton programme sera prévisible et propre dans les situations bizarres.

8. À quoi NE PAS utiliser les exceptions

Parfois, les débutants commencent à utiliser les exceptions... comme un mécanisme normal de gestion de la logique, par exemple :

try
{
    if (x < 0) throw new Exception("x doit être >= 0");
}
catch (Exception)
{
    // rollback, continuer...
}

Faut pas faire ça ! Les exceptions — c’est un outil pour les situations inattendues, rares (erreur de lecture de fichier, plantage réseau, etc.), pas pour les vérifs classiques de validité des données utilisateur. Pour ça, utilise des instructions conditionnelles (if, else) et renvoie des valeurs spéciales si besoin.

2
Mission
C# SELF, niveau 13, leçon 1
Bloqué
Division avec gestion d'erreur
Division avec gestion d'erreur
2
Mission
C# SELF, niveau 13, leçon 1
Bloqué
Gestion de la saisie de nombres incorrects
Gestion de la saisie de nombres incorrects
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION