Pourquoi devrais-je écrire toutes les déclarations dans Try-Catch?

12

Mon chef d'entreprise dit que je dois tout écrire, c'est-à-dire TOUT mon code dans les instructions Try-catch. Maintenant, je peux comprendre l'approche `` mieux vaut prévenir que guérir '' ici, mais n'est-ce pas trop farfelu de penser qu'il y aura une exception lorsque les étiquettes seront créées, la position du formulaire sera définie. y a-t-il eu des cas où des exceptions dans de telles opérations simples.

Chypre
la source
4
Cela sonne comme buzz termes par les mêmes personnes qui disent que tous SQL doit être écrit que les procédures stockées pour de meilleures performances.
spong
5
Préféreriez-vous, "Si votre code crée une erreur d'exécution, vous êtes viré." Le jeu de poulet est amusant jusqu'à ce que vous voyez votre adversaire lancer le volant et la pédale de frein par la fenêtre.
JeffO
4
@Jeff O - Je crois en fait que dans le développement de logiciels, l'adversaire est un train de marchandises.
Joris Timmermans
5
La meilleure expression que j'ai entendue pour ce style de gestion des exceptions est "Clouer le cadavre en position verticale", ce qui signifie qu'il laisse l'application dans un état inattendu. Fail Fast, Fail Loudly est une approche beaucoup plus moderne, vous pouvez donc résoudre tous les bugs.
Brook
2
Le sujet de la demande est hors de propos ... juste dire "mon chef d'entreprise dit que je devrais coder ..." est un gros drapeau rouge. C'est de la microgestion ... ce n'est pas son travail.
JoelFan

Réponses:

14

Mon chef d'entreprise dit que je dois tout écrire, c'est-à-dire TOUT mon code dans les instructions Try-catch.

Eh bien, c'est un peu exagéré et conduit juste à du code bruyant. Quels sont les avantages d'avoir tout le code (chaque méthode par exemple) écrit avec un gestionnaire try catch? Il vous indique simplement qu'une erreur doit être corrigée dans la plupart des cas. Souvent, l'exception peut et doit être évitée en premier lieu.

Un regard sur la trace de la pile est généralement suffisant pour révéler la cause dans votre code, même si la méthode défaillante n'effectue pas la capture elle-même. Il y a des moments où les développeurs corrompent les traces de pile dans les exceptions, mais c'est beaucoup plus souvent le cas lorsque vous avez beaucoup, beaucoup de gestionnaires d'exceptions. Comme n'importe quoi: un peu c'est bien, mais trop c'est du poison.

La gestion des exceptions est en effet assez simple:

Attraper les exceptions

  • chaque fois que vous avez besoin d'une action spéciale en réaction à l'exception
  • chaque fois qu'une exception laisserait le programme dans un état incohérent s'il n'est pas géré

Si vous y réfléchissez, alors il n'y a presque toujours qu'un seul endroit qui est bon pour gérer une exception qui se produit. Et donc le gestionnaire devrait être à cet endroit.

De nombreuses exceptions ne devraient même pas être levées en premier lieu, alors ne construisez pas vos structures de contrôle autour de la gestion des exceptions, essayez plutôt d'éviter l'apparition possible d'exceptions chaque fois que cela est possible.

N'oubliez pas de planter tôt lorsque les choses tournent (irréparablement) mal. Mettre tout le code dans les instructions try-catch est absurde, mais n'oubliez pas de signaler et de consigner TOUTES les exceptions.

Faucon
la source
+1 Non seulement cela conduit à un code bruyant, mais à des performances encore pires. Lorsque vous placez des instructions dans un bloc try, le compilateur HotSpot ne pourra pas appliquer les optimisations qu'il ferait autrement.
Oliver Weiler
@Oliver Weiler: Avez-vous une citation qui explique quelles optimisations le compilateur HotSpot ne fait pas dans les blocs try / catch?
Kaypro II
16

mais n'est-il pas trop cruel de penser qu'il y aura une exception lorsque les étiquettes seront créées, la position du formulaire sera définie. y a-t-il eu des cas où des exceptions dans de telles opérations simples.

Absolument oui! Il y a toujours un moyen pour que les choses tournent mal que vous n'aviez pas prévu. Et "au cœur de poulet" est une expression ridicule à utiliser dans ce contexte; le développement de logiciels ne consiste pas à prouver votre machisme en ignorant les problèmes potentiels.

Ce qui est une question valable est de savoir s'il est utile pour les exceptions à être pris au point où vos normes de codage disent qu'ils doivent. Votre déclaration se lit comme si vous deviez avoir un bloc try / catch autour de chaque corps de méthode, et c'est en effet absurde car vous ne pouvez souvent pas immédiatement faire quelque chose d'utile avec une exception, et c'est en fait tout le point des exceptions: que vous pouvez choisir de les laisser propager la pile d'appels à traiter au point approprié.

Michael Borgwardt
la source
13
Mes applications savent mieux que de lever des exceptions ou elles obtiendront le battement de leur vie. Une fois qu'ils pensent que vous avez le cœur de poulet, ils vont s'écraser partout sur vous.
JeffO
@Michael Borgwardt: hehe, vous m'avez donc dévalorisé. Vous avez voté contre cette question et le seul downvote est sur mon post. Vous semblez avoir un sérieux problème avec votre ego ou votre estime de soi. Je l'ai remarqué aussi sur d'autres quetsions. Vous savez, d'autres programmeurs ont aussi de bonnes réponses.
Falcon
@Falcon: Je n'ai rien downvote sur cette question. Je n'ai aucune idée de ce qui vous fait croire le contraire, mais si quelqu'un a un grave problème d'ego, c'est vous.
Michael Borgwardt
@Michael Borwardt: Je me trompe peut-être. Dans ce cas, je m'excuse. Il se pourrait que ce soit juste le downvote sur votre propre question qui m'a fait penser que vous avez downvote ici. Pardon.
Falcon
8

Je tournerais cela dans l'autre sens. Oui, en règle générale, la gestion des exceptions est une bonne chose, mais pouvez-vous réellement gérer chaque exception possible de manière sensée au point où elle est interceptée? Parfois, surtout si vous n'êtes pas en train d' écrire un logiciel critique mission, il est préférable de simplement crash and burn d' une certaine manière à mi-chemin contrôlé quand les choses tournent mal.

Si vous ne pouvez pas être sûr à 100% que vous pouvez gérer toutes les exceptions qui pourraient éventuellement être interceptées, vous feriez probablement mieux d'écrire une sorte de gestionnaire d'exceptions générales, en encapsulant la boucle principale du programme - la mécanique exacte de la façon de le faire évidemment dépend de ce que la langue que vous travaillez là - dedans, journal le plus de détails au sujet de l'exception que vous pouvez, sauver l' état du programme (quelque part. autre que de toutes les données stockent l'utilisateur travaille actuellement contre - rappelez - vous, il peut tout être corrompu à ce point ), etc. Ensuite, relancez l'exception et laissez le système d'exploitation la gérer comme bon lui semble. Dans ce gestionnaire d'exceptions fourre-tout, préparez-vous à une défaillance catastrophique. Ensuite, lorsque le programme est redémarré, vérifiez si cet état est utile et restaurez ce qui peut être récupéré s'il l'est; et éventuellement proposer à l'utilisateur de vous renvoyer un rapport de bogue.

un CVn
la source
5
+1: N'attrapez jamais une exception si vous ne pouvez pas immédiatement la traiter correctement. (Hélas, parfois vous devez le piéger juste pour le laisser errer à nouveau mais étiqueté comme un type différent, dans le cadre de la contrainte API: je déteste ça.)
Donal Fellows
6

Dans l'ensemble, l'utilisation de try / catch est obsolète, car le bloc catch est si cher du point de vue des ressources. L'essai / capture me rappelle la gestion des risques . La gestion des risques a deux dimensions:

  1. La probabilité que le risque se produise
  2. Les dégâts qu'il peut avoir

Maintenant, si vous sortez de votre maison, un piano qui vous tombe sur la tête quelque part alors est peu probable (peut-être 0,001%), mais peut vous tuer.

La gestion des exceptions est comme ça. Essayer le bloc n'est pas cher. Mais le bloc catch est vraiment cher, car il doit créer une table de trace de pile et faire d'autres choses. Par conséquent, en prenant une décision concernant les blocs try / catch, vous devez considérer le nombre de fois où vous avez probablement frappé le bloc catch. Si parmi 10 000 utilisations, vous ne le touchez qu'une seule fois, puis utilisez-le. Mais s'il s'agit d'un formulaire et que l'utilisateur ne le remplit probablement pas correctement 50% de fois, vous devez éviter d'y mettre un bloc try / catch.

Dans les endroits où la probabilité d'occurrence d'exception est élevé, il est recommandé d'utiliser des if {} else {}blocs pour éviter l' apparition d'exception. Par exemple, où vous souhaitez diviser deux nombres, au lieu d'écrire:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

vous devez écrire:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}
Saeed Neamati
la source
2
+1 pour utiliser if / else pour traiter les "exceptions" qui ne sont essentiellement que de la logique d'application.
Morgan Herlocker
Si c'est lié à l'utilisateur, n'oubliez pas que les ordinateurs sont massivement plus rapides que les gens. Une exception levée dans 50% des soumissions de formulaires ne devrait encore se produire que quelques fois par seconde, même avec de nombreux utilisateurs.
Donal Fellows
1
Je ne suis pas d'accord avec vous pour éviter les blocs try / catch. Essayer constamment d'anticiper les exceptions est sujet aux erreurs, coûteux en temps de développement et rend votre code plus difficile à lire. Une boucle qui génère un million d' exceptions et les intercepte prend 500 ms pour s'exécuter sur ma machine (contre 1 ms pour une boucle vide), ce qui n'est pas une différence de performances réelle dans 99,99% des cas (et tout le code de l'interface utilisateur). Vous devez utiliser des exceptions, sauf dans les cas où vous savez que la pénalité de performance est importante, car elles rendent votre code plus fiable et vous permettent de supposer que le code précédent s'est correctement exécuté.
Kaypro II
@ cosmic.osmo, récupérez-vous la trace de pile ou la rattrapez-vous simplement?
3

Vous devriez utiliser try-catch le cas échéant, mais s'il vous plaît oh s'il vous plaît ne pas intercepter toutes les exceptions et ne pas même l'enregistrer. À ce stade, c'est l'odeur de code et le travail de mauvaise qualité.

ist_lion
la source
1
+1 pour la journalisation. Les programmes dans la nature sont des boîtes noires. En cas d'échec, un journal indiquant "Voici ce qui s'est passé" permet de résoudre le problème très longtemps. J'ai eu des erreurs dans mes programmes qui n'ont pas été signalées, et elles n'ont été découvertes qu'après les avoir trouvées dans le journal.
Andrew Neely
2

Personnellement, je ne supporte pas les exceptions, elles sont TRÈS, TRÈS, TRÈS difficiles à gérer correctement. Et essayer de corrompre les données corrompues est TRÈS, TRÈS, TRÈS difficile!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

Si vous n'appelez pas toutes les fonctions comme:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

Il n'y a aucun moyen de nettoyer correctement chaque point de sortie. Les exceptions sont DIFFICILES!

La seule bonne chose à propos des exceptions est que si vous ne les attrapez pas, l'application se bloque en cas de comportement inattendu.

Codeur
la source