web-dev-qa-db-fra.com

Pourquoi ne puis-je pas écrire juste un essai sans attraper ou enfin?

Parfois, je fais ça et j'ai vu les autres le faire aussi:

Vb:

Try
    DontWannaCatchIt()
Catch
End Try

C #:

try 
{ 
    DontWannaCatchIt();
} 
catch {}

Je sais que je devrais attraper toutes les exceptions importantesque j'attends Et faites quelque chose à ce sujet, mais parfois ce n'est pas important pour - ou Est-ce que je fais quelque chose de mal?

Est-ce que cet usage du bloc try bloque incorrect et la nécessité d'au moins un catch ou finally bloque une indication de celui-ci?

Mettre à jour:

Maintenant, je comprends la raison de cela, et c'est que je devrais au moins commenter le bloc de capture vide afin que d'autres comprennent pourquoi il est vide. Je devrais aussi attraper que les exceptions que je m'attends.

Heureusement pour moi, je codifie VB afin que je puisse l'écrire dans une seule prise:

Catch ex As Exception When TypeOf ex Is IOException _
                    OrElse TypeOf ex Is ArgumentException _
                    OrElse TypeOf ex Is NotSupportedException _
                    OrElse TypeOf ex Is SecurityException _
                    OrElse TypeOf ex Is UnauthorizedAccessException
    'I don't actually care.
End Try
23
Camilo Martin

Si vous ne voulez pas l'attraper, pourquoi utilisez-vous try en premier lieu?

Une déclaration try signifie que vous croyez que quelque chose peut se tromper, et le catch dit que vous pouvez gérer suffisamment ce qui ne va pas.

Donc, dans votre estimation:

try
{
    //Something that can go wrong
}
catch
{
    //An empty catch means I can handle whatever goes wrong. If a meteorite hits the
    //datacenter, I can handle it.
}

Cette attrape avale toutes les exceptions qui se produisent. Êtes-vous en confiance dans votre code que vous pouvez gérer n'importe quoi qui ne va pas gracieusement?

La meilleure chose à faire (pour le vôtre et la santé de votre programmeur de maintenance) est d'indiquer explicitement que vous pouvez gérer gracieusement:

try
{
    //Something that could throw MeteoriteHitDatacenterException
}
catch (MeteoriteHitDatacenterException ex)
{
    //Please log when you're just catching something. Especially if the catch statement has side effects. Trust me.
    ErrorLog.Log(ex, "Just logging so that I have something to check later on if this happens.")

}
45
George Stocker

Non, vous devriez pas Catch chaque exception importante. Il est correct d'attraper et d'ignorer les exceptions que vous ne vous souciez pas, comme une erreur d'E/S s'il n'y a rien que vous puissiez faire pour le corriger et vous ne voulez pas vous soucier de la signaler à l'utilisateur.

Mais vous devez laisser des exceptions comme StackOverflowException et OutOfMemoryException propager. Ou, plus communément, NullReferenceException. Ces exceptions sont généralement des erreurs que vous n'avez pas anticipé, vous ne pouvez pas récupérer de, ne doit pas de récupérer et ne doit pas être supprimé.

Si vous voulez ignorer une exception, c'est bon pour écrire explicitement un bloc de capture vide dans le code pour cette exception particulière. Cela précise exactement quelles exceptions que vous ignorez. Ignorer les exceptions très correctement est une procédure d'opt-in, pas une option de retrait. Ayant une fonctionnalité "ignorer toutes les exceptions" qui peut alors être remplacée pour ne pas ignorer des types spécifiques serait une très mauvaise fonctionnalité de langue.

Comment savez-vous quels types d'exceptions sont importants et ne doivent pas être attrapés? Et s'il y a des exceptions, vous ne connaissez pas? Comment savez-vous que vous ne finirez pas de supprimer des erreurs importantes que vous ne connaissez pas?

try
{
}
// I don't care about exceptions.
catch
{
}
// Okay, well, except for system errors like out of memory or stack overflow.
// I need to let those propagate.
catch (SystemException exception)
{
    // Unless this is an I/O exception, which I don't care about.
    if (exception is IOException)
    {
        // Ignore.
    }
    else
    {
        throw;
    }
}
// Or lock recursion exceptions, whatever those are... Probably shouldn't hide those.
catch (LockRecursionException exception)
{
    throw;
}
// Or, uh, what else? What am I missing?
catch (???)
{
}
10
John Kugelman

Aucune prise ou finalement n'est pas valide. Catch vide ou enfin est valide. Catch vide signifie que vous ne vous souciez pas des exceptions, vous essayez simplement de faire quelque chose et peu importe si cela ne fonctionne pas, vous voulez juste continuer. Utile dans les fonctions de nettoyage par exemple.

2
fejesjoco

De plus, si vous n'avez pas à faire quelque chose à propos d'une erreur, vous devez peut-être spécifier quel type d'exception le programme doit ignorer.

Si vous devez ignorer toutes les exceptions, je ne vois pas pourquoi vous ne pouvez pas utiliser essayer de cette manière.

2
as-cii

C'est généralement une erreur. Signal d'exception, eh bien, comportement exceptionnel ; Quand une exception est lancée, cela devrait dire que quelque chose s'est mal passé. Donc, pour continuer le flux de programmes normal comme si rien ne s'est mal passé, c'est un moyen de cacher une erreur, une forme de déni. Au lieu de cela, pensez à la manière dont votre code devrait gérer le cas exceptionnel et écrire du code pour que cela se produise. Une erreur qui se propage parce que vous l'avez couverte est beaucoup plus difficile à déboguer que celui qui surface immédiatement.

2
Carl Manaster

Cela ne vous est pas facile de faire parce que cela est considéré comme une mauvaise pratique par la majorité des développeurs.

Et si une personne ajoute plus tard un appel de méthode au corps de DontWannaCatchIt() _ DO Jetez une exception pour la portée, mais elle est avalée par votre bloc de capture vide? Et s'il existe des exceptions exceptions que vous voudriez réellement attraper, mais ne vous en étiez pas réalisée à l'époque?

Si vous devez absolument le faire, essayez d'être aussi précis que possible avec le type d'exception que vous allez attraper. Sinon, peut-être la journalisation de l'exception est une option.

1
ryeguy

Une erreur existe, a été lancée et doit aller quelque part. Le flux de code normal a été abandonné et le ventilateur a besoin nettoyé.

Pas de bloc de capture = état indéterminé. Où devrait aller le code? Que devrait-il faire?

Un bloc de capture vide = erreur manipulée en l'ignorant.

Remarque: VBA a un vil "on erreur continue" ...

1
gbn

La raison pour laquelle j'ai entendu dire est que si votre essai échoue pour une raison quelconque, vous donnez le contrôle de la réponse d'erreur est hautement préférable à donner le contrôle-cadre de celui-ci, c'est-à-dire écran jaune ou erreur 500.

0
John Dunagan

et si vous écrivez seulement du code avec essayer

try
{
   int j =0;
   5/j;
}

cela équivaut à écrire

 int j =0;
   5/j;

ainsi, ESSAYE ESSAYE N'essayez pas de sens, cela ne représente que votre nombre de lignes.

maintenant, si vous écrivez Essayez d'essayer avec une prise vide ou enfin, vous êtes Explicitley instructeur d'exécution pour vous comporter différemment.

de sorte que "pourquoi je pense que le bloc d'essai vide n'est pas possible.

0
TalentTuner

Oui, c'est incorrect. C'est comme goto: un pour 100 kloc va bien, mais si vous en avez besoin de beaucoup, vous le faites mal.

Avaler des exceptions sans réactions est l'une des choses pires dans la manipulation des erreurs, et elle devrait au moins être explicite:

try  
{      
   DontWannaCatchIt(); 
}  
catch 
{
    // This exception is ignored based on Spec Ref. 7.2.a,
    // the user gets a failure report from the actual results, 
    // and diagnostic details are available in the event log (as for every exception)
} 

Le plus éloigné:

La manutention des erreurs est un aspect: dans certains contextes, une erreur doit être levée et propager la pile d'appels (par exemple, vous copiez un fichier, une copie échoue).

Appeler le même code dans un contexte différent peut nécessiter que l'erreur soit suivie, mais l'opération de continuer (par exemple, la copie de 100 fichiers, avec un journal indiquant lequel les fichiers ont échoué).

Même dans ce cas, un gestionnaire de capture vide est faux.

Avec la plupart des langues, il n'y a pas d'autre implémentation directe que d'essayer + Catch dans la boucle et de construire le journal dans le gestionnaire de capture. (Vous pouvez construire un mécanisme de flexible Mroe, bien que: avoir un gestionnaire de fil de parallèle capable de jeter ou de ranger le message. Cependant, l'interaction avec les outils de débogage subit sans support de langue direct.)


Un cas d'utilisation raisonnable implémenterait une TryX() à partir d'une X(), mais cela devrait renvoyer l'exception en question.

0
peterchen