IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Le langage C# > Gestion d'erreurs
        Comment intercepter une exception ?
        Comment écrire du code qui sera exécuté même après une exception ?
        Comment relancer une exception interceptée ?
        Comment lever une exception ?
        Comment créer une exception personnalisée ?



Comment intercepter une exception ?
auteur : tomlev
Pour intercepter un exception (erreur) qui se produit dans le code, il faut placer le code "à risque" dans un bloc try/catch. Quand une instruction du bloc try provoque une exception, l'exécution saute au prochain bloc catch qui correspond, puis l'exécution reprend à la suite du try/catch. Si aucun bloc catch ne correspond à l'exception levée, celle-ci remonte la pile des appels jusqu'à ce qu'elle soit interceptée par un bloc try/catch... ou jusqu'au plantage du programme si elle n'est jamais interceptée.

          
try
{
    AttentionCaPeutPlanter();
    Console.WriteLine("Si on est arrivé jusqu'ici, c'est que tout s'est bien passé...");
}
catch(Exception ex)
{
    // Ce code n'est exécuté que si une exception se produit
    Console.WriteLine("Une erreur s'est produite : {0}", ex.Message);
}

        
info On indique en paramètre de catch le type de l'exception à intercepter. Exception étant la classe de base de toutes les exceptions, le code catch(Exception) interceptera toutes les erreurs (sauf quelques-unes qui ne peuvent pas être interceptées). Il est généralement recommandé de n'intercepter que les erreurs qu'on est capable de gérer, il vaut donc mieux intercepter des exceptions d'un type spécifique.
On peut également intercepter plusieurs types d'exceptions différents, de la façon suivante :

          
try
{
    OperationSurUnFichier();
    Console.WriteLine("OK, traitement terminé");
}
catch(IOException ex)
{
    Console.WriteLine("Une erreur d'entrée/sortie s'est produite : {0}", ex.Message);
}
catch(UnauthorizedAccessException ex)
{
    Console.WriteLine("L'accès a été refusé : {0}", ex.Message);
}
catch(Exception ex)
{
    // Toutes les exceptions non interceptées par les deux premiers catch sont interceptées par celui-ci
    Console.WriteLine("Une erreur s'est produite : {0}", ex.Message);
}

        

Comment écrire du code qui sera exécuté même après une exception ?
auteur : tomlev
Un bloc try peut être complété par un bloc finally. Le contenu de ce bloc sera exécuté quoi qu'il arrive, même si une exception se produit. Dans ce dernier cas, le bloc catch (s'il existe) est exécuté, plus le bloc finally, puis l'exception remonte la pile si elle n'a pas été interceptée par un bloc catch (ou si elle a été relancée). Le bloc finally est particulièrement utile pour effectuer du code de "nettoyage" avant de quitter la méthode en cours.

          
public string LireLaPremiereLigneSiLeFichierExiste()
{
    StreamReader reader = null;
    try
    {
        reader = new StreamReader("MonFichier.txt");
        string line = reader.ReadLine();
        return line;
    }
    catch(FileNotFoundException ex)
    {
        // Le fichier n'existe pas, on renvoie null
        return null;
    }
    finally
    {
    	  // Quoiqu'il arrive, on ferme le fichier avant de quitter la méthode
        if (reader != null)
            reader.Close();
    }
}

        
Dans ce code, remarquez que, bien que le return se situe avant le bloc finally, ce dernier est quand même toujours exécuté avant de quitter la méthode. Notez aussi qu'il n'est pas obligatoire d'écrire un bloc catch : on peut écrire simplement un bloc try/finally si on a pas besoin de gérer l'erreur.


Comment relancer une exception interceptée ?
auteur : tomlev
Il est possible d'intercepter une exception pour l'examiner, l'écrire dans un log, etc., puis de la "relancer" pour la laisser remonter la pile d'appel jusqu'au prochain bloc try/catch. Pour cela, on utilise le mot-clé throw, sans spécifier de paramètre :

          
try
{
    AttentionCaPeutPlanter();
}
catch(Exception ex)
{
    Console.WriteLine("Oups, une erreur s'est produite : {0}", ex.Message);

    // On laisse l'erreur remonter
    throw;
}

        
warning Il est très important d'utiliser l'instruction throw et non throw ex : en effet, throw ex réinitialise les informations sur la pile d'appels contenues dans l'exception, ce qui empêche de déterminer avec précision l'origine de l'erreur initiale.
Il est également possible "d'enrichir" une exception pour lui ajouter des informations. Il faut dans ce cas lancer une nouvelle exception qui "englobe" celle qu'on a interceptée :

          
try
{
    AttentionCaPeutPlanter();
}
catch(Exception ex)
{
    // On enrichit l'erreur d'un message personnalisé, et on la relance
    throw new Exception("Aie, l'appel à AttentionCaPeutPlanter à planter... voir l'erreur interne pour les détails", ex);
}

        
L'exception ainsi englobée est accessible via la propriété InnerException de l'exception qu'on a relancée.


Comment lever une exception ?
auteur : tomlev
Si votre code reçoit un argument incorrect, se trouve dans une situation invalide, etc., vous pouvez le signaler en levant une exception grâce au mot-clé throw. Par exemple, la méthode suivante lève une exception de type ArgumentNullException si le paramètre nom est null :

          
public void DisBonjour(string nom)
{
    if (nom == null)
        throw new ArgumentNullException("nom", "Le nom n'est pas spécifié");

    Console.WriteLine("Bonjour {0}", nom);
}

        

Comment créer une exception personnalisée ?
auteurs : cardi, tomlev
Toute exception dérive de la classe Exception. Pour créer une exception personnalisée, il faut donc créer une nouvelle classe dérivée de la classe Exception.
Il est également conseillé de fournir un constructeur qui permet de définir l'exception interne, afin de fournir plus d'informations sur l'exception.

          
public class MonException : Exception
{
    public MonException()
        : base("Exception personnalisée")
    { }

    public MonException(string message)
        : base("Exception personnalisée : " + message)
    { }
    
    public MonException(string message, Exception innerException)
        : base("Exception personnalisée : " + message, innerException)
    { }
}
        
info Dans la première version de .NET, il était recommandé de créer les exceptions personnalisées en héritant de la classe ApplicationException, afin de pouvoir distinguer les exceptions de l'application de celles du .NET Framework. Etant donné que certaines exceptions du framework ne respectaient pas cette recommandation, cette recommandation a été supprimée car n'a plus de sens (voir en l'article de Krzysztof Cwalina à ce sujet, ainsi que le lien ci-dessous).
lien : fr Méthodes conseillées pour la gestion des exceptions (MSDN)


Consultez les autres F.A.Q's


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2010 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.