C# Language Exception Anti-patrons


Exemple

Exceptions à la déglutition

Il faut toujours relancer l’exception de la manière suivante:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw;
}

Relancer une exception comme ci-dessous masquera l'exception d'origine et perdra la trace de la pile d'origine. On ne devrait jamais faire ça! La trace de la pile avant la capture et la relance sera perdue.

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw ex;
}

Gestion des exceptions de baseball

Il ne faut pas utiliser les exceptions comme substitut aux constructions de contrôle de flux normales comme les instructions if-then et les boucles while. Cet anti-pattern est parfois appelé gestion des exceptions de baseball .

Voici un exemple d'anti-pattern:

try
{
    while (AccountManager.HasMoreAccounts())
    {
        account = AccountManager.GetNextAccount();
        if (account.Name == userName)
        {
            //We found it
            throw new AccountFoundException(account);
        }
    }
}
catch (AccountFoundException found)
{
    Console.Write("Here are your account details: " + found.Account.Details.ToString());
}

Voici une meilleure façon de le faire:

Account found = null;
while (AccountManager.HasMoreAccounts() && (found==null))
{
    account = AccountManager.GetNextAccount();
    if (account.Name == userName)
    {
        //We found it
        found = account;
    }
}
Console.Write("Here are your account details: " + found.Details.ToString());

attraper (Exception)

Il n'y a presque pas (certaines ne disent rien!) De raisons pour intercepter le type d'exception générique dans votre code. Vous ne devriez intercepter que les types d'exception que vous prévoyez, car vous masquez autrement les bogues dans votre code.

try 
{
     var f = File.Open(myfile);
     // do something
}
catch (Exception x)
{
     // Assume file not found
     Console.Write("Could not open file");
     // but maybe the error was a NullReferenceException because of a bug in the file handling code?
}

Mieux vaut faire:

try 
{
     var f = File.Open(myfile);
     // do something which should normally not throw exceptions
}
catch (IOException)
{
     Console.Write("File not found");
}
// Unfortunatelly, this one does not derive from the above, so declare separatelly
catch (UnauthorizedAccessException) 
{
     Console.Write("Insufficient rights");
}

Si une autre exception se produit, nous autorisons délibérément l'application à tomber en panne, elle intervient donc directement dans le débogueur et nous pouvons résoudre le problème. Nous ne devons pas expédier un programme où toute autre exception que celle-ci se produit de toute façon, donc ce n'est pas un problème d'avoir un crash.

Ce qui suit est un mauvais exemple, car il utilise des exceptions pour contourner une erreur de programmation. Ce n'est pas pour ça qu'ils sont conçus.

public void DoSomething(String s)
{
     if (s == null)
         throw new ArgumentNullException(nameof(s));
     // Implementation goes here
}

try 
{    
     DoSomething(myString);
}
catch(ArgumentNullException x)
{
    // if this happens, we have a programming error and we should check
    // why myString was null in the first place.
}