17. Exceptions
Jusqu’à présent, nous n’avons jamais parlé de la gestion des erreurs en C#. En simplifiant, une erreur est l’occurrence d’une situation inattendue lors de l’exécution d’un programme.
Les erreurs dans le monde .NET, dans la meilleure tradition orientée objet (Java, C++, etc.) sont représentées avec des exceptions : une hiérarchie de classe entière pour la gestion des événements indésirables.
Les exceptions sont “affichés” lorsqu’une situation anormale se produit, comme une erreur. Vous pouvez les ignorer, avec le risque d’avoir de mauvaises surprises au moment de l’exécution, ou vous pouvez les intercepter et les gérer.
Ceci implique l’utilisation d’une construction créée spécifiquement pour l’interception des exceptions : try-catch-finally.
try { // Code qui pourrait déclencher une exception. } catch { // Code à exécuter en cas d'exception. } finally { // Code à exécuter dans chaque cas }
Si le code exécuté dans le bloc try déclenche une exception, il est capturé et le bloc catch est exécuté. Dans tous les cas, le bloc finally est également exécuté.
Dans la construction try-catch, vous devez spécifier au moins un catch ou une clause finally ; vous pouvez indiquer plus de captures, une pour chaque type d’erreur que vous voulez gérer, alors que vous ne pouvez insérer qu’une clause finally.
Dans la clause catch, vous pouvez indiquer le type d’exception que vous souhaitez gérer ; par exemple :
catch (OverflowException ex) { // Code à exécuter en cas d'erreur d'overflow. } catch (DivideByZeroException ex) { // Code à exécuter en cas d'erreur due // à une division par 0. }
Le premier bloc est exécuté si une erreur d’overflow se produit, par exemple lors de la tentative d’affectation d’une variable à une valeur en dehors de sa définition. La seconde est invoquée si une division est faite par 0.
Dans les deux cas, l’objet “ex” contient diverses informations sur l’erreur. Par exemple, la propriété ex.Message renvoie une chaîne décrivant la cause de l’exception.
Mettons maintenant à jour l’application que nous avons faite dans la leçon précédente en ajoutant la gestion des erreurs. En particulier, nous considérons l’instruction
picImage.Image = Bitmap.FromFile(txtNomFichier.Text);
Dans le cas où le fichier spécifié n’existe pas, la méthode FromFile déclenche une exception de type FileNotFoundException. Insérons donc cette instruction dans un try … catch block :
try { picImage.Image = Bitmap.FromFile(txtNomFichier.Text); } catch (FileNotFoundException){ MessageBox.Show(“Impossible de trouver le fichier ” + txtNomFichier.Text + “.”, “Erreur”, MessageBoxButtons.OK, MessageBoxIcon.Error); }
Comme les exceptions sont également des classes, elles sont également regroupées dans les namespace. Par exemple, pour que le Framework sache où rechercher la classe FileNotFoundException, la clause “using” doit être ajoutée à l’espace de noms “System.IO”.
Chaque fois que vous essayez de charger un fichier, une exception “FileNotFoundException” se produit, le bloc catch correspondant est exécuté, ce qui affiche une boîte de message. L’erreur de fichier non trouvée, cependant, n’est pas la seule qui peut arriver en essayant d’ouvrir un fichier : par exemple, si la mémoire disponible n’est pas suffisante pour terminer le téléchargement, vous obtenez une erreur de type OutOfMemoryException.
Encore une fois, si vous appuyez sur le bouton «Afficher» sans taper aucun nom de fichier, une exception ArgumentException se produit.
Ensuite, nous ajoutons un second bloc catch pour traiter tous les autres cas, en obtenant :
try { picImage.Image = Bitmap.FromFile(txtNomFichier.Text); } catch (FileNotFoundException) { MessageBox.Show( “Impossible de trouver le fichier ” + txtNomFichier.Text + “.”, “Erreur”, MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { MessageBox.Show( “Erreur lors du chargement : ” + ex.Message, “Erreur”, MessageBoxButtons.OK, MessageBoxIcon.Error); }
Étant donné que Exception est la classe de base à partir de laquelle toutes les autres exceptions sont dérivées, le second bloc catch est exécuté chaque fois que la méthode FromFile renvoie une exception qui n’est pas de type «FileNotFoundException» (et n’en dérive pas).
Dans ce cas, nous avons utilisé l’information contenue dans l’exception “ex” pour connaître exactement l’origine de l’erreur.
Il est toujours préférable d’éviter le traitement des exceptions, en essayant de prévoir, dans la mesure du possible, les causes pouvant mener à une situation inattendue : un abus de try … catch, en fait, peut peser dans un programme. Par exemple, dans notre application, l’erreur ArgumentException peut toujours être évitée simplement en invoquant la méthode FromFile uniquement si quelque chose a été tapé dans la zone de texte.
Étiquette :Concepts avancés, Exception, overflow