Imaginez que vous créez un lecteur vidéo en JavaScript. Ce lecteur vidéo boucle la vidéo de l'utilisateur à plusieurs reprises à l'aide d'une fonction récursive et, à cause de cela, le navigateur déclenchera un too much recursion
RangeError
à un moment donné.
Personne n'utilisera probablement autant la fonction de boucle. Votre application ne lancera jamais cette erreur, même si l'utilisateur a quitté l'application en boucle pendant une semaine, mais elle existe toujours. Pour résoudre le problème, vous devrez repenser le fonctionnement du bouclage dans votre application, ce qui prendra beaucoup de temps. Que faire? Pourquoi?
Correction du bug
Laissez le bug
Ne devriez-vous pas seulement corriger les bugs dans lesquels les gens tomberont? Quand la correction de bogues devient-elle exagérée, si c'est le cas?
MODIFIER:
Si l'approche récursive ne provoquant pas de bogue réel vous inquiète, supposez qu'à chaque fois que le joueur boucle une vidéo, une variable soit augmentée de 1
. Après 253 boucle cette variable va déborder et votre programme ne pourra pas la gérer, levant une exception.
Vous devez être pragmatique.
S'il est peu probable que l'erreur se déclenche dans le monde réel et que le coût de la réparation soit élevé, je doute que beaucoup de gens considèrent que c'est une bonne utilisation des ressources à corriger. Sur cette base, je dirais de le laisser mais assurez-vous que le piratage est documenté pour vous ou votre successeur dans quelques mois (voir le dernier paragraphe).
Cela dit, vous devez utiliser ce problème comme une "expérience d'apprentissage" et la prochaine fois que vous effectuez une boucle, n'utilisez pas une boucle récursive inutilement.
Soyez également prêt pour ce rapport de bogue. Vous seriez surpris de voir à quel point les utilisateurs finaux sont bons pour repousser les limites et découvrir les défauts. Si cela devient un problème pour les utilisateurs finaux, vous devrez le résoudre - alors vous serez heureux d'avoir documenté le piratage.
Il y avait un bogue similaire dans Windows 95 qui provoquait les ordinateurs se bloquent après 49,7 jours . Il n'a été remarqué que quelques années après sa sortie, car très peu de systèmes Win95 sont restés en place aussi longtemps. Il y a donc un point: les bogues peuvent être rendus non pertinents par d'autres bogues plus importants.
Ce que vous devez faire est une évaluation des risques pour le programme dans son ensemble et une évaluation de l'impact pour les bogues individuels.
Etc. Cela affecte le bug triage, le processus de décision des bugs à corriger. Presque tous les logiciels d'expédition ont de très longues listes de bugs mineurs qui n'ont pas encore été jugés suffisamment importants pour être corrigés.
Les autres réponses sont déjà très bonnes, et je sais que votre exemple n'est qu'un exemple, mais je veux souligner une grande partie de ce processus qui n'a pas encore été discutée:
Vous devez identifier vos hypothèses, puis tester ces hypothèses par rapport aux cas d'angle.
En regardant votre exemple, je vois quelques hypothèses:
D'autres personnes ont discuté de la première hypothèse, mais regardez la deuxième hypothèse: que se passe-t-il si ma vidéo ne dure qu'une fraction de seconde?
Et bien sûr, ce n'est peut-être pas un cas d'utilisation très courant. Mais êtes-vous vraiment sûr que personne mettra en ligne une très courte vidéo? Vous supposez que les vidéos sont d'une durée minimale, et vous ne vous êtes probablement même pas rendu compte que vous supposiez quelque chose! Cette hypothèse pourrait-elle provoquer d'autres bogues à d'autres endroits de votre application?
Les hypothèses non identifiées sont une énorme source de bugs.
Comme je l'ai dit, je sais que votre exemple n'est qu'un exemple, mais ce processus d'identification de vos hypothèses (qui est souvent plus difficile qu'il n'y paraît), puis de penser à des exceptions à ces hypothèses est un facteur énorme pour décider où passer votre temps.
Donc, si vous vous retrouvez à penser "Je ne devrais pas avoir à programmer autour de cela, car cela ne se produira jamais", alors vous devriez prendre un certain temps pour vraiment examiner cette hypothèse. Vous penserez souvent aux cas d'angle qui pourraient être plus courants que vous ne le pensiez à l'origine.
Cela étant dit, il y a un moment où cela devient un exercice futile. Vous ne vous souciez probablement pas de savoir si votre application JavaScript fonctionne parfaitement sur une calculatrice TI-89, donc passer du temps sur cela est simplement perdu.
Les autres réponses ont déjà couvert cela, mais trouver cette ligne entre "c'est important" et "c'est une perte de temps" n'est pas une science exacte, et cela dépend de beaucoup de facteurs qui peuvent être complètement différents d'un personne ou entreprise à une autre.
Mais une grande partie de ce processus consiste d'abord à identifier vos hypothèses, puis à essayer de reconnaître les exceptions à ces hypothèses.
Je vous recommande de lire le document suivant:
Fiabilité et ses menaces: une taxonomie
Entre autres, il décrit différents types de défauts pouvant survenir dans votre programme. Ce que vous avez décrit s'appelle un défaut dormant , et dans cet article, il est décrit comme ceci:
Un défaut est actif lorsqu'il produit une erreur, sinon il est dormant. Un défaut actif est soit a) un défaut interne qui était auparavant inactif et qui a été activé par le processus de calcul ou les conditions environnementales, ou b) un défaut externe. L'activation par défaut est l'application d'une entrée (le modèle d'activation) à un composant qui provoque l'activation d'un défaut dormant. La plupart des défauts internes oscillent entre leurs états dormants et actifs
Cela dit, tout se résume à un rapport coûts-avantages. Le coût comprendrait trois paramètres:
Les deux premiers sont cruciaux. S'il s'agit d'un bug qui se manifesterait une fois sur une lune bleue et/ou que personne ne s'en soucierait, ou qui aurait une solution de contournement parfaitement bonne et pratique, alors vous pouvez le documenter en toute sécurité comme un problème connu et passer à un autre plus difficile et plus tâches importantes. Cependant, si le bogue entraînait l'échec d'une transaction financière ou interrompait un long processus d'enregistrement, frustrant ainsi l'utilisateur final, vous devez agir en conséquence. Le troisième paramètre est quelque chose que je déconseille fortement. Pour reprendre les mots de Vito Corleone:
Ce n'est pas personnel. C'est des affaires.
Si vous êtes un professionnel, laissez de côté les émotions et agissez de manière optimale. Cependant, si l'application que vous écrivez est un de vos passe-temps, vous êtes émotionnellement impliqué et le troisième paramètre est aussi valide que n'importe lequel pour décider de corriger ou non un bug.
Ce bug ne reste à découvrir que le jour où quelqu'un place votre lecteur sur un écran d'accueil exécutant une présentation de l'entreprise 24h/24 et 7j/7. C'est donc toujours un bug.
La réponse à que faites-vous? est vraiment une décision commerciale, pas une décision d'ingénierie:
tl; dr C'est pourquoi RESOLVED/WONTFIX
est une chose. N'en abusez pas - la dette technique peut s'accumuler si vous ne faites pas attention. Est-ce un problème fondamental avec votre conception, susceptible de causer d'autres problèmes à l'avenir? Ensuite, corrigez-le. Autrement? Laissez-le jusqu'à ce qu'il devienne une priorité (si jamais il le fait).
Il y a en fait trois erreurs dans la situation que vous décrivez:
L'absence d'un processus pour évaluer toutes les erreurs enregistrées (vous avez enregistré l'erreur dans votre ticket/backlog/quel que soit le système que vous avez en place, non?) Pour déterminer si elle doit être corrigée ou non. Il s'agit d'une décision de gestion.
Le manque de compétences dans votre équipe qui conduit à l'utilisation de solutions défectueuses comme celle-ci. Il est urgent de régler ce problème pour éviter de futurs problèmes. (Commencez à apprendre de vos erreurs.)
Le problème que la vidéo peut cesser de s'afficher après une très longue période.
Sur les trois erreurs seulement (3) n'a peut-être pas besoin d'être corrigé.
Surtout dans les grandes entreprises (ou les grands projets), il existe un moyen très pragmatique d'établir quoi faire.
Si le coût de la correction est supérieur au retour que la correction apportera, gardez le bogue. Viceversa si le correctif renverra plus que son coût, corrigez le bogue.
Dans votre exemple de scénario, cela dépend du nombre d'utilisateurs que vous prévoyez de perdre par rapport au nombre d'utilisateurs que vous gagnerez si vous développez de nouvelles fonctionnalités au lieu de corriger ce bogue coûteux.
Il y a beaucoup de réponses ici discutant de l'évaluation du coût du bug à réparer plutôt que de le laisser. Ils contiennent tous de bons conseils, mais j'aimerais ajouter que le coût d'un bogue est souvent sous-estimé, voire extrêmement sous-estimé. La raison en est que les insectes existants embrouillent les eaux pour un développement et un entretien continus. Faire en sorte que vos testeurs gardent une trace de plusieurs bogues "ne résoudra pas" tout en naviguant dans votre logiciel en essayant de trouver nouvea les bogues rendent leur travail plus lent et plus sujet aux erreurs. Quelques bugs "ne seront pas corrigés" qui sont peu susceptibles d'affecter les utilisateurs finaux ralentiront toujours le développement et le résultat sera plus bogué.
Une chose que j'ai apprise au cours de mes années de codage, c'est qu'un bogue va revenir. L'utilisateur final le découvrira toujours et fera rapport. Que vous corrigiez le bogue ou non est "simplement" une question de priorité et d'échéance.
Nous avons eu des bugs majeurs (à mon avis, majeurs) qui ont été décidés de ne pas être corrigés dans une seule version, seulement pour devenir un bouchon d'exposition pour la prochaine version parce que l'utilisateur final est tombé dessus à maintes reprises. Le même vice-versa - nous avons été poussés à corriger un bogue dans une fonctionnalité que personne n'utilise, mais c'était pratique à voir pour la direction.
Il y a trois choses ici:
C'est un côté de la médaille. Dans une certaine mesure, je pense qu'il est bon d'insister sur la correction de bugs (ou de mauvaises implémentations, même s'ils "fonctionnent"), même si personne ne le remarque.
Regardez-le de cette façon: le vrai problème n'est pas nécessairement le bogue, dans votre exemple, mais le fait qu'un programmeur ait pensé que c'était une bonne idée d'implémenter la boucle de cette façon, en premier lieu. Il était évident dès le premier instant que ce n'était pas une bonne solution. Il y a maintenant deux possibilités:
Le programmeur n'a tout simplement pas remarqué. Eh bien ... un programmeur devrait développer une intuition sur la façon dont son code fonctionne. Ce n'est pas comme si la récursivité était un concept très difficile. En corrigeant le bug (et en suant tout le travail supplémentaire), il apprend peut-être quelque chose et s'en souvient, ne serait-ce que pour éviter le travail supplémentaire à l'avenir. Si la raison était qu'il n'avait tout simplement pas assez de temps, la direction pourrait apprendre que les programmeurs do ont besoin de plus de temps pour créer un code de meilleure qualité.
Le programmeur l'a remarqué, mais l'a jugé "pas un problème". Si cela reste en place, une culture de laissez-faire se développera, ce qui conduira finalement à des bugs là où ça fait vraiment mal. Dans ce cas particulier, peu importe. Mais que faire si ce programmeur développe une application bancaire la prochaine fois et décide qu'une certaine constellation ne se produira jamais. Ensuite, c'est le cas. Mauvais moments.
C'est l'autre côté. De bien sûr vous auriez probablement, dans ce cas particulier, pas résolu le bogue. Mais attention, il y a du pragmatisme, puis du pragmatisme. Un bon pragmatisme consiste à trouver une solution rapide mais solide et bien fondée à un problème. C'est-à-dire que vous évitez de trop concevoir, mais les choses que vous mettez en œuvre sont toujours bien pensées. Le mauvais pragmatisme, c'est quand vous piratez quelque chose ensemble qui fonctionne "comme ça" et qui se cassera à la première occasion.
En cas de doute, échouez vite et échouez fort.
Cela signifie, entre autres, que votre code remarque la condition d'erreur, pas l'environnement.
Dans cet exemple, le moins que vous puissiez faire est de faire en sorte que l'erreur d'exécution matérielle ("profondeur de pile dépassée" ou quelque chose du genre) ne se produise pas, en la remplaçant par une exception matérielle de votre choix. Vous pouvez, par exemple, avoir un compteur global et décider arbitrairement que vous renflouez après 1000 vidéos (ou n'importe quel nombre est suffisamment élevé pour ne jamais se produire en utilisation normale, et suffisamment faible pour continuer à fonctionner dans la plupart des navigateurs). Donnez ensuite à cette exception (qui peut être une exception générique, par exemple un RuntimeException
en Java, ou une simple chaîne en JavaScript ou Ruby) un message significatif. Vous n'avez pas à aller jusqu'à créer un nouveau type d'exceptions ou quoi que vous fassiez dans votre langage de programmation particulier.
De cette façon, vous avez
Ma convention est de préfixer ces messages d'erreur avec le mot "Paranoia:". C'est un signe clair pour moi et tout le monde que je jamais m'attends à ce que cette erreur disparaisse. Je peux clairement les séparer des "vraies" exceptions. Si j'en vois un comme ça dans une interface graphique ou un fichier journal, je sais avec certitude que j'ai un problème sérieux - je ne m'attendais pas à ce qu'ils se produisent, après tout. À ce point, je passe en mode crunch (avec une bonne chance de le résoudre rapidement et assez facilement, car je sais exactement où le problème est survenu, ce qui me sauve de beaucoup de faux débogage).
Un post-it sur le bureau d'un développeur senior sur mon lieu de travail dit
Est-ce que ça aide quelqu'un?
Je pense que c'est souvent un bon point de départ pour le processus de réflexion. Il y a toujours beaucoup de choses à corriger et à améliorer - mais quelle valeur ajoutez-vous réellement? ... que ce soit en termes de convivialité, de fiabilité, de maintenabilité, de lisibilité, de performances ... ou de tout autre aspect.
Mais cela ne peut pas devenir une béquille pour les développeurs paresseux ...
Pour déclarer que la probabilité d'occurrence est très faible et que les conséquences sont légères, l'équipe de développement doit comprendre le code, les schémas d'utilisation et la sécurité.
Notre système éducatif n'enseigne pas très bien la probabilité et la logique. La plupart des personnes, y compris la plupart des ingénieurs logiciels, ont une logique brisée et une intuition de proabilité brisée. Une expérience avec des problèmes du monde réel et une expérience avec des simulations approfondies sont le seul moyen que je connais pour résoudre ce problème.
Il est important de créer plusieurs journaux pour pouvoir suivre les modèles d'utilisation. Remplissez le code avec des affirmations de choses qui, selon vous, ne devraient pas se produire. Vous serez surpris qu'ils le fassent. De cette façon, vous pourrez confronter votre intuition avec des données solides et les affiner.
Dans un site de commerce électronique sur lequel j'ai travaillé il y a longtemps, un autre programmeur a fait une erreur: dans une condition obscure, le système a débité le client d'un cent de moins que celui enregistré dans les journaux. J'ai découvert le bogue parce que j'ai fait des rapports pour identifier les différences entre les journaux et les soldes des comptes afin de rendre le système comptable plus résistant. Je n'ai jamais corrigé ce bug car la différence était très petite. La différence a été calculée quotidiennement et était inférieure à 2,00 $ US par mois. Il se trouve que nous développions un tout nouveau système qui, dans un an, devrait remplacer le système actuel. Cela n'a aucun sens de détourner des ressources d'un projet potentiellement rentable pour réparer quelque chose qui coûte 2,00 $ US par mois et a été soumis à une mesure de contrôle appropriée.
Oui, il existe des bogues qui n'ont pas besoin d'être corrigés immédiatement, qui ne sont pas suffisamment importants pour retarder le développement de nouvelles fonctionnalités. Cependant, le système doit avoir le contrôle de l'occurence de ce bogue pour s'assurer qu'il est petit car nous ne pouvons pas faire confiance à notre propre intuition.
Trois choses me viennent à l'esprit:
First, l'impact d'un bogue identifié doit être minutieusement étudié avant de pouvoir décider de laisser le bogue dans le code. fait de manière responsable. (Dans votre exemple, j'ai tout de suite pensé à la fuite de mémoire que représente la pile toujours croissante et qui pourrait rendre votre navigateur de plus en plus lent à chaque récursivité.) Cette approfondie l'enquête prend souvent plus de temps que la correction du bogue, donc je préfère le corriger dans la plupart des cas.
Second, les bugs ont tendance à avoir plus d'impact qu'on ne le pense au début. Nous connaissons tous très bien le code de travail car c'est le cas "normal". Les bogues, par contre, sont une "exception". Bien sûr, nous avons tous vu beaucoup de bugs, mais nous avons vu beaucoup plus de code de travail dans l'ensemble. Nous avons donc plus d'expérience sur le comportement du code de travail que sur le comportement du code buggy. Il existe des millions de livres sur le code de travail et ce qu'il fera dans quelles situations. Il n'y a pratiquement rien sur le comportement du code buggé.
La raison en est simple: les bogues ne sont pas l'ordre mais le chaos . Ils ont souvent une trace d'ordre en eux (ou l'inverse: ils ne détruisent pas complètement l'ordre), mais leur nature de buggy est une destruction de l'ordre que le programmeur voulait. Le chaos lui-même a tendance à ne pas être estimé correctement. Il est beaucoup plus difficile de dire ce qu'un programme avec un bug fera que ce qu'un programme correct fera juste parce qu'il ne correspond plus à nos schémas mentaux.
Troisième, votre exemple contenait l'aspect que la correction du bogue signifierait devoir repenser le programme. (Si vous supprimez cet aspect, la réponse est simple: corrigez le bogue, cela ne devrait pas prendre trop de temps car aucune refonte n'est nécessaire. Sinon :) Dans un tel cas, je perdrais confiance dans le programme tel qu'il est actuellement conçu. La refonte serait un moyen de restaurer cette confiance.
Tout cela dit, les programmes sont des choses que les gens utilisent, et une fonctionnalité manquante ou un deuxième bogue vraiment lourd ailleurs peut avoir la priorité sur la correction de votre bogue. Bien sûr, alors prenez la voie pragmatique et faites d'abord d'autres choses. Mais n'oubliez jamais qu'une première estimation rapide de l'impact d'un bogue peut être complètement fausse.