Pourquoi la gestion des exceptions est-elle mauvaise?

89

Le langage Go de Google n'a pas d'exceptions en tant que choix de conception, et Linus de la renommée de Linux a appelé les exceptions de la merde. Pourquoi?

Joemoe
la source
2
Le créateur de ZeroMQ écrit sur la façon dont il pense que c'était une erreur de l'écrire en C ++ (principalement à cause de la gestion des erreurs) 250bpm.com/blog:4
serbaut
Go n'a peut-être pas d'exceptions, mais il a des "paniques" dont vous pouvez "récupérer" (alors que les instructions différées sont toujours exécutées) et qui fournissent un flux de contrôle non local ...
Kerrek SB
Voici un bel article lightra.com/papers/exceptionsharmful (Gestion des exceptions considérée comme nocive)
masterxilo
Afaics, les exceptions peuvent être simulées dans Go avec un passe-partout significatif , bien que ce point puisse être plus significatif pour transpiler à partir d'un sucre de syntaxe que pour écrire le passe-partout manuellement.
Shelby Moore III

Réponses:

81

Les exceptions rendent très facile l'écriture de code où une exception levée cassera les invariants et laissera les objets dans un état incohérent. Ils vous obligent essentiellement à vous rappeler que la plupart des déclarations que vous faites peuvent potentiellement être lancées et à les gérer correctement. Cela peut être délicat et contre-intuitif.

Considérez quelque chose comme ceci comme un exemple simple:

class Frobber
{
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:
    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

En supposant que la FrobManagervolonté de deletela FrobObject, cela semble OK, non? Ou peut-être pas ... Imaginez alors si l'un FrobManager::HandleFrob()ou l' autre operator newlève une exception. Dans cet exemple, l'incrément de m_NumberOfFrobsn'est pas annulé. Ainsi, toute personne utilisant cette instance de Frobberva avoir un objet potentiellement corrompu.

Cet exemple peut sembler stupide (ok, j'ai dû m'étirer un peu pour en construire un :-)), mais le point à retenir est que si un programmeur ne pense pas constamment aux exceptions, et s'assure que chaque permutation d'état est lancée à chaque fois qu'il y a des lancers, vous avez des ennuis de cette façon.

À titre d'exemple, vous pouvez y penser comme vous pensez aux mutex. Dans une section critique, vous comptez sur plusieurs instructions pour vous assurer que les structures de données ne sont pas corrompues et que les autres threads ne peuvent pas voir vos valeurs intermédiaires. Si l'une de ces déclarations ne s'exécute pas au hasard, vous vous retrouvez dans un monde de douleur. Maintenant, supprimez les verrous et la concurrence, et pensez à chaque méthode comme ça. Considérez chaque méthode comme une transaction de permutations sur l'état de l'objet, si vous voulez. Au début de votre appel de méthode, l'objet doit être à l'état propre et à la fin, il doit également y avoir un état propre. Entre les deux, variablefoo peut être incompatible avecbar, mais votre code finira par rectifier cela. Les exceptions signifient que n'importe laquelle de vos déclarations peut vous interrompre à tout moment. Il incombe à vous dans chaque méthode individuelle de faire les choses correctement et de revenir en arrière lorsque cela se produit, ou d'ordonner vos opérations afin que les lancers n'affectent pas l'état de l'objet. Si vous vous trompez (et il est facile de faire ce genre d'erreur), l'appelant finit par voir vos valeurs intermédiaires.

Des méthodes comme RAII, que les programmeurs C ++ aiment mentionner comme la solution ultime à ce problème, contribuent largement à la protection contre cela. Mais ce n'est pas une solution miracle. Il s'assurera que vous libérez des ressources lors d'un lancement, mais ne vous libère pas de devoir penser à la corruption de l'état de l'objet et aux appelants qui voient des valeurs intermédiaires. Donc, pour beaucoup de gens, c'est plus facile à dire, par décision de style de codage, sans exception . Si vous limitez le type de code que vous écrivez, il est plus difficile d'introduire ces bogues. Sinon, il est assez facile de faire une erreur.

Des livres entiers ont été écrits sur le codage sécurisé des exceptions en C ++. De nombreux experts se sont trompés. Si c'est vraiment si complexe et a tant de nuances, c'est peut-être un bon signe que vous devez ignorer cette fonctionnalité. :-)

Asveikau
la source
9
Réponse intéressante, mais elle ne reflète rien dans mon expérience de programmation. Donc, je suppose que c'est soit spécifique à la culture (peut-être plus un problème en Java ou C ++ que, disons, Python) ou spécifique au domaine.
ddaa
39
Les exceptions écrites dans un langage géré utilisant un modèle try-catch-finally ne doivent jamais laisser un état invalide si elles sont écrites correctement; puisque l'exécution du bloc finally est garantie, les objets peuvent y être désalloués. Le reste doit être pris en charge par des variables hors de portée et par le garbage collection.
Robert Harvey
7
@ddaa Le problème est certainement possible en Python. Le résultat est généralement un bogue difficile à reproduire. Peut-être avez-vous été particulièrement méticuleux ou chanceux. Mais alors, vous avez raison de dire que c'est plus un problème en C ++, où le bogue le plus courant d'un mauvais EH est une fuite de mémoire. J'ai essayé de souligner que les fuites ne sont pas le problème le plus grave. @Robert GC atténuera les fuites de mémoire, mais je ne suis pas sûr que le code géré vous libère des erreurs du programmeur. En particulier, si quelqu'un ne fait pas attention à la sécurité des exceptions parce qu'il ne pense pas que c'est un problème dans sa langue, ce n'est pas un bon signe.
asveikau
4
@lzprgmr il y en a certainement: les exceptions vous permettent de gérer les diff. types d'erreurs à diff. place dans le code. La gestion d'une erreur de connexion peut nécessiter une reconnexion, mais pas au milieu d'une fonction profondément imbriquée. Vous voulez faire remonter cela au gestionnaire de connexions ou quelque chose comme ça. Ensuite, traiter les valeurs de retour vous oblige à vérifier les erreurs à chaque appel, et à remonter manuellement (dans le cas d'une erreur de réinitialisation de connexion par exemple). Aussi, les valeurs de retour s'empilent dans les appels imbriqués: func3 peut retourner -1, func2 appelle func3, renvoie -2 sur ses erreurs, -1 pour func3, etc.
abourget
3
J'ai voté contre, mais j'ai inversé cette décision parce que c'est une raison pour laquelle les exceptions sont méprisées. Cependant, à mon avis, presque n'importe quelle méthode ou morceau de code peut échouer. Vous ne pouvez pas gérer chaque condition d'erreur en y introduisant une valeur de retour. Vous perdrez des informations sur l'erreur. Penser que vous pouvez tout garder bien synchronisé en vérifiant chaque instruction et en effectuant le nettoyage conduit à un code très alambiqué - détecter une erreur sur plusieurs déclarations et nettoyer une ou deux ressources qui ne sont pas GC est beaucoup plus propre.
Maarten Bodewes
50

La raison pour laquelle Go n'a pas d'exceptions est expliquée dans la FAQ sur la conception du langage Go:

Les exceptions sont une histoire similaire. Un certain nombre de modèles d'exceptions ont été proposés, mais chacun ajoute une complexité significative au langage et à l'exécution. De par leur nature même, les exceptions couvrent les fonctions et peut-être même les goroutines; ils ont de vastes implications. On s'inquiète également de l'effet qu'ils auraient sur les bibliothèques. Ils sont, par définition, exceptionnels mais l'expérience avec d'autres langages qui les prennent en charge montre qu'ils ont un effet profond sur la spécification des bibliothèques et des interfaces. Ce serait bien de trouver une conception qui leur permette d'être vraiment exceptionnelles sans encourager les erreurs courantes à se transformer en flux de contrôle spécial qui oblige chaque programmeur à compenser.

Tout comme les génériques, les exceptions restent une question ouverte.

En d'autres termes, ils n'ont pas encore trouvé comment prendre en charge les exceptions dans Go d'une manière qu'ils jugent satisfaisante. Ils ne disent pas que les exceptions sont mauvaises en soi ;

MISE À JOUR - Mai 2012

Les concepteurs de Go sont maintenant descendus de la clôture. Leur FAQ dit maintenant ceci:

Nous pensons que le couplage d'exceptions à une structure de contrôle, comme dans l'idiome try-catch-finally, aboutit à un code alambiqué. Cela a également tendance à encourager les programmeurs à qualifier un trop grand nombre d'erreurs ordinaires, telles que l'échec de l'ouverture d'un fichier, d'exceptionnelles.

Go adopte une approche différente. Pour une gestion simple des erreurs, les retours à valeurs multiples de Go permettent de signaler facilement une erreur sans surcharger la valeur de retour. Un type d'erreur canonique, associé aux autres fonctionnalités de Go, rend la gestion des erreurs agréable mais assez différente de celle d'autres langues.

Go a également quelques fonctions intégrées pour signaler et récupérer des conditions vraiment exceptionnelles. Le mécanisme de récupération est exécuté uniquement dans le cadre de la destruction de l'état d'une fonction après une erreur, ce qui est suffisant pour gérer une catastrophe mais ne nécessite aucune structure de contrôle supplémentaire et, lorsqu'il est bien utilisé, peut entraîner un code de gestion des erreurs propre.

Consultez l'article Différer, paniquer et récupérer pour plus de détails.

Donc, la réponse courte est qu'ils peuvent le faire différemment en utilisant un retour à valeurs multiples. (Et ils ont de toute façon une forme de gestion des exceptions.)


... et Linus de la renommée Linux a appelé les exceptions de la merde.

Si vous voulez savoir pourquoi Linus pense que les exceptions sont de la merde, le mieux est de chercher ses écrits sur le sujet. La seule chose que j'ai retracée jusqu'à présent est cette citation qui est intégrée dans quelques e-mails sur C ++ :

"L'ensemble de la gestion des exceptions C ++ est fondamentalement cassé. Il est particulièrement cassé pour les noyaux."

Vous remarquerez qu'il parle d'exceptions C ++ en particulier, et non d'exceptions en général. (Et les exceptions C n'ont apparemment quelques problèmes qui les rendent difficiles à utiliser correctement.)

Ma conclusion est que Linus n'a pas du tout qualifié les exceptions (en général) de "merde"!

Stephen C
la source
30
Je déteste quand ils cachent des informations en les mettant dans la FAQ. :)
brian d foy
7
Notez que Linus commence cet e-mail avec "C ++ est un langage horrible". et continue de déclamer à quel point il déteste à la fois le C ++ et les personnes qui choisissent d'y programmer. Par conséquent, je ne pense pas que son opinion sur les exceptions de C ++ puisse être considérée comme fiable étant donné son opinion quelque peu biaisée envers C ++.
Pharap
1
@ Salut-Angel - Comme le dit le texte que j'ai cité: "Pour une gestion simple des erreurs, les retours multi-valeurs de Go permettent de signaler facilement une erreur sans surcharger la valeur de retour." . Voilà comment c'est lié. Quoi qu'il en soit, je cite le raisonnement des concepteurs de Go. Si vous voulez discuter, discutez avec >> eux <<.
Stephen C
1
@ Salut-Angel - Je n'ai pas écrit ces paragraphes. Je les ai simplement cités. Si vous avez un problème avec eux, vous devriez probablement en discuter avec les auteurs. En théorie, j'aurais pu fournir un tutoriel sur le langage Go comme contexte. Mais pour être franc, les personnes qui ne comprennent pas la terminologie Go peuvent visiter le site Web Go pour découvrir ce que tout cela signifie.
Stephen C
1
".. résulte en un code alambiqué" Il y a longtemps, j'ai écrit un programme C avec de nombreuses opérations de chaîne. Chaque méthode consistait à allouer de la mémoire, puis à vérifier si l'allocation était réussie. Il est apparu que la majorité du code ne faisait que vérifier les allocations. N'est-ce pas compliqué? C ++ avec des exceptions a été un excellent sauvetage pour moi.
robsosno
29

Les exceptions ne sont pas mauvaises en soi, mais si vous savez qu'elles vont arriver souvent, elles peuvent coûter cher en termes de performances.

La règle de base est que les exceptions doivent signaler les conditions exceptionnelles et que vous ne devez pas les utiliser pour contrôler le déroulement du programme.

Robert Harvey
la source
9
@Robert: "vous ne devriez pas les utiliser pour contrôler le déroulement du programme", je n'y ai pas pensé de cette façon, nouvelle perspective pour moi: P +1
okw
2
Cela dépend aussi vraiment de la langue. Il est difficile d'éviter les exceptions si vous programmez en Java par exemple.
Charles Salvia
2
@Charles: Je pense que le fait est que les exceptions sont appropriées dans les situations qui indiquent un bogue, un système mal configuré ou des entrées déraisonnables. La plupart des exceptions de bibliothèque Java peuvent être évitées dans le code de "workflow normal".
Artelius
6
ils ne doivent pas coûter cher. par exemple, vous pouvez implémenter un "essai" qui ne coûte aucun temps d'exécution, et demander à "lancer" de rechercher des gestionnaires d'exceptions dans une table en fonction des adresses de l'appelant qu'il voit sur la pile ... Je dirais que les principales raisons de ne pas les exceptions d'utilisation ne sont pas du tout liées aux performances.
asveikau
Reformulé; la question fait clairement allusion à l'utilisation d'exceptions en général, ou à ne pas utiliser d'exceptions du tout (elles sont de la merde ou ne sont même pas dans la langue). Votre réponse montre uniquement pourquoi les exceptions sont mauvaises pour les performances lorsqu'elles sont utilisées pour le flux de contrôle du programme.
Maarten Bodewes
26

Je ne suis pas d'accord avec «ne jeter des exceptions que dans une situation exceptionnelle». Bien que généralement vrai, c'est trompeur. Les exceptions concernent les conditions d' erreur (échecs d'exécution).

Quel que soit le langage que vous utilisez, procurez-vous une copie de Framework Design Guidelines : Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition). Le chapitre sur le lancement d'exceptions est sans égal. Quelques citations de la première édition (la 2ème à mon travail):

  • NE renvoyez PAS de codes d'erreur.
  • Les codes d'erreur peuvent être facilement ignorés, et le sont souvent.
  • Les exceptions sont le principal moyen de signaler les erreurs dans les cadres.
  • Une bonne règle de base est que si une méthode ne fait pas ce que son nom suggère, elle doit être considérée comme un échec au niveau de la méthode, entraînant une exception.
  • NE PAS utiliser d'exceptions pour le flux normal de contrôle, si possible.

Il y a des pages de notes sur les avantages des exceptions (cohérence de l'API, choix de l'emplacement du code de gestion des erreurs, robustesse améliorée, etc.) Il y a une section sur les performances qui comprend plusieurs modèles (Tester-Doer, Try-Parse).

Les exceptions et la gestion des exceptions ne sont pas mauvaises. Comme toute autre fonctionnalité, ils peuvent être mal utilisés.

TrueWill
la source
3
Je ne suis pas d'accord là-dessus. Je ne suis pas contre les exceptions, et ce livre est indispensable, mais il est biaisé vers le développement .NET et C #.
3
Je sais que c'est ancien, je voulais juste commenter qu'il semble y avoir un désaccord de style général entre le type .NET et le type * nix. Toutes les bibliothèques que j'ai utilisées en tant que développeur Linux utilisent des codes de retour, et les guides de style * nix que j'ai lus (comme mon entreprise et Google par exemple) disent simplement "nous ne faisons pas d'exceptions". Pensez simplement que c'est intéressant.
jarvisteve
1
Les frameworks doivent traiter les exceptions différemment des applications des utilisateurs finaux. Les frameworks n'ont pas de moyen de traiter les erreurs autres que de lever une exception, contrairement aux applications grand public.
0x6C38
11

Du point de vue de golang, je suppose que le fait de ne pas avoir de gestion des exceptions rend le processus de compilation simple et sûr.

Du point de vue de Linus, je comprends que le code du noyau est TOUT sur les cas de coin. Il est donc logique de refuser les exceptions.

Les exceptions ont du sens dans le code s'il est acceptable de laisser tomber la tâche actuelle sur le sol, et lorsque le code de cas commun a plus d'importance que la gestion des erreurs. Mais ils nécessitent la génération de code à partir du compilateur.

Par exemple, ils conviennent à la plupart des codes de haut niveau destinés aux utilisateurs, tels que le code d'application Web et de bureau.

ddaa
la source
Mais ce qui est vrai pour le code du noyau l'est également pour les processus serveur natifs de longue durée.
Lothar
11

Les exceptions en elles-mêmes ne sont pas «mauvaises», c'est la façon dont les exceptions sont parfois gérées qui a tendance à être mauvaise. Plusieurs directives peuvent être appliquées lors de la gestion des exceptions pour aider à résoudre certains de ces problèmes. Certains d'entre eux incluent (mais ne sont sûrement pas limités à):

  1. N'utilisez pas d'exceptions pour contrôler le flux du programme - c'est-à-dire ne vous fiez pas aux instructions "catch" pour modifier le flux de la logique. Non seulement cela a tendance à masquer divers détails autour de la logique, mais cela peut entraîner de mauvaises performances.
  2. Ne lancez pas d'exceptions depuis une fonction lorsqu'un "statut" retourné aurait plus de sens - ne lancez des exceptions que dans une situation exceptionnelle. La création d'exceptions est une opération coûteuse et gourmande en performances. Par exemple, si vous appelez une méthode pour ouvrir un fichier et que ce fichier n'existe pas, lancez une exception «FileNotFound». Si vous appelez une méthode qui détermine si un compte client existe, renvoyez une valeur booléenne, ne renvoyez pas une exception «CustomerNotFound».
  3. Pour déterminer s'il faut ou non gérer une exception, n'utilisez pas de clause "try ... catch" sauf si vous pouvez faire quelque chose d'utile avec l'exception. Si vous ne parvenez pas à gérer l'exception, laissez-la simplement remonter la pile des appels. Sinon, les exceptions peuvent être "avalées" par le gestionnaire et les détails seront perdus (à moins que vous ne renvoyiez l'exception).
Jeff Bramwell
la source
2
Le retour du statut est une chose délicate. J'ai vu beaucoup trop de code avec une méthode GetCustomer renvoyant une entité Customer en cas de succès ou null en cas d'échec. Dans de nombreux cas, le code d'appel n'a jamais vérifié le résultat, mais a immédiatement accédé au client. Cela a fonctionné la plupart du temps ...
TrueWill
3
Mais si GetCustomer lève une exception au lieu de renvoyer null, le code client doit toujours gérer l'exception. Que ce soit en vérifiant la valeur nulle ou en gérant les exceptions, la responsabilité incombe au code client - s'il ne fait pas correctement les choses, alors tôt ou tard quelque chose explosera.
Chris
1
@TrueWill Les langages qui prennent en charge les modèles / génériques résolvent ce problème en renvoyant un Option<T>plutôt que de nullnos jours. Je viens d'être introduit dans Java 8 par exemple, en prenant un indice de Guava (et d'autres).
Maarten Bodewes
@owlstead Ouais. J'adore la monade peut-être. C'est une bonne façon de procéder si votre langue le prend en charge et propose une correspondance de modèles.
TrueWill
@owlstead Encore une fois, ce que Chris a dit est toujours valable pour cela - l'utilisateur doit se souvenir d'appeler la fonction .orElse (defaultObject), ou tout idiome choisi par la langue en question. En fin de compte, ce sont finalement les programmeurs qui sont le problème, plutôt que la méthode de gestion des erreurs.
Pharap
9

Les arguments typiques sont qu'il n'y a aucun moyen de dire quelles exceptions sortiront d'un morceau de code particulier (selon la langue) et qu'elles ressemblent trop à gotos, ce qui rend difficile le suivi mental de l'exécution.

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

Il n'y a certainement pas de consensus sur cette question. Je dirais que du point de vue d'un programmeur C hard-core comme Linus, les exceptions sont définitivement une mauvaise idée. Un programmeur Java typique se trouve cependant dans une situation très différente.

Tim Sylvester
la source
1
Le code C a une sorte d'exceptions, mais d'une manière différente. Vous devez envelopper chaque appel à une fonction non triviale dans ifs, ce qui rend l'utilisation de cette langue un casse-tête!
RCIX
1
Il y a aussi le truc setjmp/ longjmp, ce qui est plutôt mauvais.
Tim Sylvester
9
Voulez-vous vraiment suivre les conseils d'un homme qui valorise les programmeurs de Duct Tape et qui ne croit pas que les tests unitaires soient nécessaires? joelonsoftware.com/items/2009/09/23.html
TrueWill
4
C'est une erreur classique (ou triche) dans une discussion où les arguments sur le sujet sont remplacés par des références de personnalité. C'est généralement le signe d'une discussion dégénérative.
Petr Gladkikh
1
@PetrGladkikh La discussion a commencé avec le PO faisant référence à l'opinion de Linus ... que la triche est connue comme l'erreur de l'appel à l'autorité. La discussion ne peut que monter en flèche à partir de là, et ce n'est pas une "triche" de répondre à la question de savoir pourquoi Linus n'aime pas les exceptions en se référant à sa personnalité.
Jim Balter
7

Les exceptions ne sont pas mauvaises. Ils s'intègrent bien avec le modèle RAII de C ++, qui est la chose la plus élégante du C ++. Si vous avez déjà un tas de code qui n'est pas exceptionnellement sûr, alors ils sont mauvais dans ce contexte. Si vous écrivez des logiciels de très bas niveau, comme le système d'exploitation Linux, alors ils sont mauvais. Si vous aimez joncher votre code avec un tas de vérifications de retour d'erreur, alors elles ne sont pas utiles. Si vous n'avez pas de plan pour le contrôle des ressources lorsqu'une exception est levée (que les destructeurs C ++ fournissent), elles sont mauvaises.

Paul
la source
7
RAII est utile même sans exceptions.
Mark Ransom
4
cependant, les exceptions ne sont pas utiles sans RAII (ou une autre gestion automatique des ressources).
Greg Rogers
+1 pour signaler les situations où les exceptions ne sont pas appropriées et que les exceptions ne sont pas intrinsèquement mauvaises.
Pharap
4

Un bon cas d'utilisation des exceptions est donc ...

Supposons que vous soyez sur un projet et que chaque contrôleur (environ 20 principaux différents) étend un seul contrôleur de superclasse avec une méthode d'action. Ensuite, chaque contrôleur fait un tas de choses différentes les unes des autres en appelant les objets B, C, D dans un cas et F, G, D dans un autre cas. Des exceptions viennent à la rescousse dans de nombreux cas où il y avait des tonnes de code de retour et que CHAQUE contrôleur le traitait différemment. J'ai frappé tout ce code, jeté l'exception appropriée de "D", l'ai attrapé dans la méthode d'action du contrôleur de la superclasse et maintenant tous nos contrôleurs sont cohérents. Auparavant, D renvoyait null pour PLUSIEURS cas d'erreur différents dont nous voulons informer l'utilisateur final mais que nous ne pouvions pas et je ne l'ai pas fait '

oui, nous devons nous soucier de chaque niveau et de tout nettoyage / fuite de ressources, mais en général aucun de nos contrôleurs n'avait de ressources à nettoyer après.

Dieu merci, nous avons eu des exceptions ou j'aurais été dans un énorme refactor et j'ai perdu trop de temps sur quelque chose qui devrait être un simple problème de programmation.

Dean Hiller
la source
1
+1 Facilement l'un des meilleurs arguments pour utiliser les exceptions que j'ai lu. J'aurais pu utiliser des exemples plus détaillés (c'est-à-dire un diagramme UML, un pseudo-code ou du code réel), mais le point sur la cohérence des sous-classes est un bon point. De plus, le fait que vos preuves soient anecdotiques montre que les exceptions sont utiles dans des situations réelles et que l'utilité est le principal objectif de toute fonctionnalité linguistique.
Pharap
juste en plus, si vous êtes dans scala, vous pouvez à la place retourner Try [ResponseType] qui représente une exception ou une réponse réelle. Vous pouvez ensuite suivre le même schéma que j'échappe à ci-dessus sans exceptions réelles autres que celles qui sont mises à l'essai. Ensuite, c'est comme chaque méthode que vous avez renvoie 1 + n types de réponse qui, à mon avis, sont nécessaires. Cependant, dans scala, nous retournons Future [response] qui fonctionne un peu comme Try mais peut aider avec une programmation plus asynchrone.
Dean Hiller
2

Théoriquement, ils sont vraiment mauvais. Dans un monde mathématique parfait, vous ne pouvez pas avoir de situations d'exception. Regardez les langages fonctionnels, ils n'ont pas d'effets secondaires, donc ils n'ont pratiquement pas de source pour des situations non exceptionnelles.

Mais la réalité est une autre histoire. Nous avons toujours des situations «inattendues». C'est pourquoi nous avons besoin d'exceptions.

Je pense que nous pouvons penser aux exceptions comme au sucre de syntaxe pour ExceptionSituationObserver. Vous recevez juste des notifications d'exceptions. Rien de plus.

Avec Go, je pense qu'ils introduiront quelque chose qui traitera des situations «inattendues». Je peux deviner qu'ils essaieront de rendre cela moins destructeur comme exceptions et plus comme logique d'application. Mais ce n'est que ma supposition.

Mike Chaliy
la source
2
"Regardez les langages fonctionnels, ils n'ont pas d'effets secondaires, donc ils n'ont pratiquement pas de source pour des situations non exceptionnelles." C'est une exagération flagrante.
Stephen C
3
Qu'est-ce que 5/0 en mathématiques? Arcsin (200)? Sqrt (-1)? Les mathématiques ont des tas de situations exceptionnelles.
Robert Fraser
3
Ce ne sont pas des situations exceptionnelles ... elles n'ont simplement aucun sens ... et à cause de cela pourraient être implémentées comme des exceptions ... mais pourraient également être implémentées comme des flacons de conditions préalables .. donc cela dépend de la mise en œuvre technique.
Mike Chaliy
3
@MikeChaliy - Je suis désolé, mais ce n'est que du sophisme. Vous pouvez appliquer ce genre de raisonnement pour dire qu'il n'y a AUCUNE situation d'exception dans quoi que ce soit, JAMAIS. En réalité, les expressions mathématiques qui n'ont pas de sens (ou qui n'ont pas de valeur définie) SONT exceptionnelles. Cela ne signifie pas qu'ils doivent être traités en lançant et en capturant des exceptions ... mais si vous ne le faites pas, vous avez besoin de valeurs spéciales (comme Inf et Nan) ou d'opérations qui renvoient plusieurs valeurs. En bref, ces cas nécessitent une sorte de traitement spécial.
Stephen C
1
Les ordinateurs sont des machines à états. Pas un monde mathématique parfait.
Arunav Sanyal
1

Le paradigme de gestion des exceptions de C ++, qui forme une base partielle pour celui de Java, et à son tour .net, introduit quelques bons concepts, mais présente également de sérieuses limitations. L'une des principales intentions de conception de la gestion des exceptions est de permettre aux méthodes de s'assurer qu'elles satisferont leurs post-conditions ou de lever une exception, et également de s'assurer que tout nettoyage qui doit se produire avant qu'une méthode puisse se fermer, se produira. Malheureusement, les paradigmes de gestion des exceptions de C ++, Java et .net échouent tous à fournir un bon moyen de gérer la situation où des facteurs inattendus empêchent le nettoyage attendu. Cela signifie à son tour qu'il faut soit risquer que tout s'arrête brutalement si quelque chose d'inattendu se produit (l'approche C ++ pour gérer une exception se produit lors du déroulement de la pile),

Même si la gestion des exceptions serait généralement bonne, il n'est pas déraisonnable de considérer comme inacceptable un paradigme de gestion des exceptions qui ne fournit pas un bon moyen de gérer les problèmes qui surviennent lors du nettoyage après d'autres problèmes. Cela ne veut pas dire qu'un framework ne pourrait pas être conçu avec un paradigme de gestion des exceptions qui pourrait garantir un comportement raisonnable même dans des scénarios de défaillance multiple, mais aucun des principaux langages ou frameworks ne peut encore le faire.

supercat
la source
1

Je n'ai pas lu toutes les autres réponses, donc cela peut déjà avoir été mentionné, mais une critique est qu'elles provoquent la rupture des programmes en longues chaînes, ce qui rend difficile la traçabilité des erreurs lors du débogage du code. Par exemple, si Foo () appelle Bar () qui appelle Wah () qui appelle ToString (), le fait de pousser accidentellement les mauvaises données dans ToString () finit par ressembler à une erreur dans Foo (), une fonction presque totalement indépendante.

kingfrito_5005
la source
0
  • L'exception non traitée est généralement mauvaise.
  • L'exception mal gérée est mauvaise (bien sûr).
  • Le «bien / mal» de la gestion des exceptions dépend du contexte / de la portée et de la pertinence, et non pour le plaisir de le faire.
okw
la source
0

D'accord, réponse ennuyeuse ici. Je suppose que cela dépend vraiment de la langue. Lorsqu'une exception peut laisser des ressources allouées derrière, elle doit être évitée. Dans les langages de script, ils abandonnent ou surchargent des parties du flux d'application. Cela n'est pas apprécié en soi, mais échapper à des erreurs presque fatales avec des exceptions est une idée acceptable.

Pour la signalisation d'erreur, je préfère généralement les signaux d'erreur. Tout dépend de l'API, du cas d'utilisation et de la gravité, ou si la journalisation suffit. J'essaye aussi de redéfinir le comportement et à la throw Phonebooks()place. L'idée étant que les «exceptions» sont souvent des impasses, mais un «répertoire» contient des informations utiles sur la récupération d'erreurs ou d'autres voies d'exécution. (Pas encore trouvé de bon cas d'utilisation, mais continuez à essayer.)

mario
la source
0

Pour moi, le problème est très simple. De nombreux programmeurs utilisent le gestionnaire d'exceptions de manière inappropriée. Plus de ressources linguistiques, c'est mieux. Être capable de gérer les exceptions, c'est bien. Un exemple de mauvaise utilisation est une valeur qui doit être un entier non vérifiée, ou une autre entrée qui peut diviser et ne pas être vérifiée pour la division de zéro ... la gestion des exceptions peut être un moyen facile d'éviter plus de travail et de réflexion, le programmeur peut vouloir faire un raccourci sale et appliquer une gestion des exceptions ... La déclaration: "un code professionnel n'échoue JAMAIS" peut être illusoire, si certains des problèmes traités par l'algorithme sont incertains par sa propre nature. Peut-être que dans les situations inconnues par nature, il est bon d'entrer en jeu le gestionnaire d'exceptions. Les bonnes pratiques de programmation font débat.

iuri
la source
Le problème n'est pas (ou ne devrait pas être) de savoir si le code peut échouer - un problème plus important est de savoir dans quelle mesure, si le code échoue, on se soucie des détails. Si l'on essaie de charger un document et que l'une des méthodes de "lecture des données" échoue, on se fiche souvent de savoir laquelle, car l'effet est le même malgré tout: le document ne peut pas être chargé. Conceptuellement, la gestion des exceptions devrait être bonne pour cela. Le problème est que les paradigmes de gestion des exceptions de .NET et Java ne fournissent aucun moyen agréable de distinguer les exceptions «ennuyeuses» qui devraient être regroupées de celles qui ne le devraient pas.
supercat du