Cela continue de m'étonner que, de nos jours, des produits qui ont des années d'utilisation à leur actif, construits par des équipes de professionnels, continuent à ce jour - ne fournissent pas de messages d'erreur utiles à l'utilisateur. Dans certains cas, l'ajout de quelques informations supplémentaires pourrait faire économiser des heures de travail à un utilisateur.
Un programme qui génère une erreur l'a générée pour une raison. Il a tout à sa disposition pour informer autant que possible l'utilisateur, pourquoi quelque chose a échoué. Et pourtant, il semble que la fourniture d'informations pour aider l'utilisateur est de faible priorité. Je pense que c'est un énorme échec.
Un exemple vient de SQL Server. Lorsque vous essayez de restaurer une base de données en cours d'utilisation, elle ne vous le permet pas. SQL Server sait quels processus et applications y accèdent. Pourquoi ne peut-il pas inclure des informations sur les processus qui utilisent la base de données? Je sais que tout le monde ne transmet pas d' Applicatio_Name
attribut à sa chaîne de connexion, mais même un indice sur la machine en question pourrait être utile.
Un autre candidat, également SQL Server (et mySQL) est le joli string or binary data would be truncated
message d'erreur et ses équivalents. La plupart du temps, une simple lecture de l'instruction SQL qui a été générée et le tableau montre quelle colonne est le coupable. Ce n'est pas toujours le cas, et si le moteur de base de données a détecté l'erreur, pourquoi ne peut-il pas nous faire gagner du temps et nous dire simplement de quelle fichue colonne il s'agissait? Sur cet exemple, vous pourriez faire valoir qu'il peut y avoir un impact sur les performances de le vérifier et que cela gênerait le rédacteur. Très bien, je vais acheter ça. Que diriez-vous, une fois que le moteur de base de données sait qu'il y a une erreur, il effectue une comparaison rapide après coup, entre les valeurs qui devaient être stockées et les longueurs de colonne. Affichez ensuite cela à l'utilisateur.
Les horribles adaptateurs de table d'ASP.NET sont également coupables. Les requêtes peuvent être exécutées et on peut recevoir un message d'erreur indiquant qu'une contrainte quelque part est violée. Merci pour ça. Il est temps de comparer mon modèle de données avec la base de données, car les développeurs sont trop paresseux pour fournir même un numéro de ligne ou des exemples de données. (Pour mémoire, je n'utiliserais jamais cette méthode d'accès aux données par choix , c'est juste un projet dont j'ai hérité!).
Chaque fois que je lève une exception de mon code C # ou C ++, je fournis tout ce que j'ai à la disposition de l'utilisateur. La décision a été prise de le jeter, donc plus je peux donner d'informations, mieux c'est. Pourquoi ma fonction a-t-elle levé une exception? Qu'est-ce qui a été adopté et qu'est-ce qui était attendu? Il me faut juste un peu plus de temps pour mettre quelque chose de significatif dans le corps d'un message d'exception. Enfer, cela ne fait que m'aider pendant mon développement, car je sais que mon code jette des choses qui ont du sens.
On pourrait faire valoir que les messages d'exception compliqués ne devraient pas être affichés pour l'utilisateur. Bien que je ne sois pas d'accord avec cela, c'est un argument qui peut facilement être apaisé en ayant un niveau de verbosité différent selon votre build. Même dans ce cas, les utilisateurs d'ASP.NET et de SQL Server ne sont pas vos utilisateurs habituels et préféreraient quelque chose de plein de verbosité et d'informations délicieuses, car ils peuvent retrouver leurs problèmes plus rapidement.
Pourquoi les développeurs pensent qu'il est acceptable, de nos jours, de fournir la quantité minimale d'informations lorsqu'une erreur se produit?
Il est 2011 les gars, venez sur .
la source
Réponses:
Bien qu'il existe de nombreux exemples de mauvais messages d'erreur qui ne devraient tout simplement pas l'être, vous devez garder à l'esprit qu'il n'est pas toujours possible de fournir les informations que vous souhaitez voir.
Il y a aussi le souci d'exposer trop d'informations, ce qui peut conduire les développeurs à des erreurs de prudence. (Je vous promets que le jeu de mots n'était pas prévu, mais je ne le retire pas maintenant que je l'ai remarqué.)
Parfois, il y a aussi le fait qu'un message d'erreur complexe est inutile pour l'utilisateur final. Faire face à la surcharge d'informations n'est pas nécessairement une bonne approche pour les messages d'erreur. (Cela peut être mieux enregistré pour la journalisation.)
la source
For further information, see log20111701.txt
. Ce serait un pas dans la bonne direction.Les développeurs ne sont pas les bonnes personnes pour écrire des messages d'erreur.
Ils voient l'application sous le mauvais angle. Ils sont extrêmement conscients de ce qui s'est mal passé dans le code, mais n'abordent souvent pas le logiciel du point de vue de la tâche à accomplir. Par conséquent, les informations importantes pour le développeur ne sont pas nécessairement des informations importantes pour l'utilisateur.
la source
La vue caritative:
Le développeur a travaillé en étroite collaboration avec le code et a eu du mal à comprendre quelqu'un qui ne comprenait pas son fonctionnement. En conséquence, ils pensent que les messages d'erreur sont corrects, ils n'ont tout simplement pas un bon cadre de référence pour les juger.
Les messages d'erreur intelligents sont en fait difficiles à faire. Non seulement les écrire, mais vous devez trouver tout ce qui pourrait mal tourner, évaluer la probabilité et fournir des informations utiles (qui varient presque certainement en fonction du contexte) à la personne qui lit le message pour lui permettre de le corriger.
Pour la plupart des applications, il est difficile de faire une bonne affaire pour le temps de faire ce genre de chose ainsi que le prochain développeur le voudrait vraiment car les erreurs ne se produisent pas souvent. De plus, si vous aviez ce temps supplémentaire, ne devriez-vous pas le consacrer à arrêter les erreurs plutôt qu'à en rendre compte?
La vue non charitable:
La réalité se situe probablement quelque part entre les deux, bien que mon expérience me dise en fait que c'est beaucoup plus ancien que tardif - en fait, c'est en fait assez difficile et demande beaucoup d'efforts pour faire face à quelque chose qui ne se produira probablement pas.
la source
Process Handle Raped By Spawned Injector, Quitting SYstem.
.... utilisateur: "wtf ai-je fait?`). Mais dans le cas de SQL Server / ASP.NET, je pense que plus d'efforts auraient pu être faits :)string/binary data
erreur qui extrait toutes les informations de colonne de ladite table, examine les valeurs passées et montre quelles colonnes auraient été en violation. C'était trivial. Peut-être que je rique trop parce que mes exemples de cas sont triviaux, mais je comprends parfaitement que ce n'est pas toujours le cas. La façon dont nous empêchons les injecteurs engendrés de violer pourrait bien être difficile :)Malheureusement, des messages d'erreur plus utiles coûtent du temps au développeur, ce qui équivaut à l'argent de l'entreprise. Les produits sont assez chers à construire tels quels. Oui, ce serait génial d'avoir des messages d'erreur plus utiles, et je suis d'accord qu'il devrait y en avoir plus utiles. Cependant, c'est juste une réalité de la vie que lorsque vous êtes sous un délai, et que l'argent est en jeu, vous devez couper quelque chose. «Des messages d'erreur plus jolis», comme les gestionnaires peuvent le voir, seront probablement la première chose à faire.
la source
J'accepte que les messages d'erreur soient aussi précis que possible.
L'une des raisons des messages d'erreur génériques est probablement l'utilisation de codes d'erreur. Lorsque vous utilisez des exceptions, vous êtes libre de transmettre tout ce dont vous avez besoin dans le message d'erreur. En utilisant des codes retour, il n'y a pas de place pour encoder un nom de colonne. Peut-être que l'erreur est gérée par une fonction générique qui ne connaît pas le contexte et traduit simplement le code d'erreur en une chaîne.
la source
la source
De manière générale, vous devez considérer que toute erreur ou situation exceptionnelle est - exactement cela: exceptionnelle. Il recoupe la procédure planifiée et conçue. Il est incompatible avec la façon dont les choses devaient fonctionner. Si ce n'était pas le cas, il ne serait pas nécessaire de renflouer avec une erreur abandonnée.
Nous, les programmeurs, sommes formés pour prendre soin de l'autoprotection de cette procédure planifiée. Ainsi, nous incluons régulièrement des vérifications d'intégrité pour vérifier nos hypothèses. Lorsque ces vérifications de santé mentale échouent, nous savons simplement que le plan a échoué en quelque sorte ...
Votre demande - cela peut sembler du bon sens du point de vue de l'utilisateur - est impossible à satisfaire si vous considérez la réalité du fonctionnement d'un tel système. Vous demandez une déclaration ordonnée avec des informations bien organisées et appropriées ajoutées. De plus, vous demandez même que cette présentation se déroule d'une manière qui corresponde à la conception générale de l'application / manipulation. De toute évidence, cette information existe quelque part dans le système. Évidemment, il existe même là-bas de manière ordonnée et bien organisée (espérons-le). MAIS au moment où l'erreur se produit, personne n'a jamais prévu de rendre ces informations disponibles. Une erreur est toujours une perte de contrôle partielle.Cette perte de contrôle peut se produire à différents niveaux. Il se peut que le système se comporte au moment de l'exécution différemment que prévu. Mais il se pourrait aussi que la mise en œuvre effective se soit avérée beaucoup plus difficile et différente dans les détails alors prévus, et il n'y avait aucune disposition budgétaire pour gérer cette situation de manière satisfaisante. C'est aussi une perte de contrôle partielle.
Pour relier cela à l'exemple concret que vous avez donné: si, au moment de l'erreur, le nom et le type de la colonne du tableau étaient connus, ainsi que la longueur de l'espace requis, il n'y aurait aucune raison de faire une erreur, non? Nous pourrions simplement corriger la situation et procéder comme prévu. Le fait même que nous soyons obligés de soulever une erreur nous montre que les choses ont mal tourné. Le fait même que ces informations ne soient pas à portée de main est l'exception .
Ce que j'écris ici peut sembler évident et simple bon sens. Mais en réalité, il est extrêmement difficile à saisir. Nous essayons constamment de le comprendre en appliquant des catégories morales - comme il doit y avoir un coupable, il doit y avoir une mauvaise personne paresseuse qui ne se soucie pas du pauvre utilisateur, il doit y avoir des hommes d'affaires cupides qui ont fait un moyen de calcul bon marché. Tout cela est complètement hors de propos
La possibilité d'une perte de contrôle découle du fait même que nous faisons les choses de manière planifiée et ordonnée .
la source
Je travaille en tant qu'ingénieur de support pour une société de logiciels et nous voyons souvent des messages d'erreur qui sont nouveaux pour nous. Souvent, lorsque je les renvoie à notre équipe de développement, ils doivent rechercher le message dans la source de l'application.
Il me semble que même s'il n'était pas présenté aux utilisateurs, cela nous ferait gagner beaucoup de temps si l'équipe de développement ajoutait une note à un document d'index de message d'erreur ou à une base de données chaque fois qu'elle en ajoutait une nouvelle, cela la rendrait beaucoup plus rapide pour nous de trouver la cause des problèmes des clients et de leur faire gagner du temps aussi ...
la source
Le problème que vous voyez là est en fait l'un des effets secondaires d'une bonne encapsulation et de la dissimulation d'informations.
Les systèmes modernes sont extrêmement compliqués. Il y a peu de chances que le développeur moyen soit capable de tenir, dans sa tête, un modèle mental de l'ensemble du système de l'interface utilisateur au binaire brut pendant qu'il code une tâche particulière.
Ainsi, alors qu'un développeur est assis et code, disons, le bit qui restaure un fichier de base de données, son modèle mental est entièrement rempli des bits entourant l'acte de restauration d'un fichier de base de données. Il doit (et je suppose, je n'ai pas écrit ce code) lire un fichier, vérifier les propriétés, lire les versions, sauvegarder les données existantes, choisir une stratégie de fusion / écrasement, etc. Très probablement, s'il y a même un passage considération à l'interface utilisateur, son dans la chaîne d'erreur qu'il écrit dans un gestionnaire d'exceptions. Quelque chose comme:
Dans cet exemple, les informations utiles que vous demandez en termes de processus qui pourraient utiliser le fichier, ou même d'autres threads dans la base de données, sont complètement hors de portée (par programme). Il peut y avoir des centaines de classes qui traitent des fichiers DB; importer dans ces classes des informations sur tous les autres processus utilisant les fichiers, ou des fonctionnalités pour accéder au système de fichiers et regarder les autres processus en cours d'exécution (en supposant que ces processus sont même sur CET ordinateur) entraîneraient ce qu'on appelle une abstraction qui fuit ; il y a un coût direct de productivité.
C'est ainsi que ces types d'erreurs peuvent persister dans les temps modernes. De toute évidence, ils POURRAIENT tous être corrigés; mais dans de nombreux cas, il y a beaucoup plus de frais généraux que l'on pourrait penser (dans ce cas par exemple, vous devrez peut-être que cette fonction traverse l'énumération des connexions et des partages réseau pour voir si une machine distante utilise ce fichier de base de données pour certains raison) et le coût est loin d’être négligeable.
la source
GenericException
, je pourrais 1) Demander auProcesses
sous - système une liste de processus. 2) Demandez à chaque processus quelle base de données il utilise. 3) Faites correspondre le processus avec la base de données affectée à celle que j'essaie d'écraser, 4) lancez uneDatabaseInUse(dbName, processName, applicationName
exception. :)Mon préféré était (à la fin des années 70) le compilateur Univac Fortran IV, lors de la lecture des non-chiffres, fidèlement annoncé
la source
Je crois que la majorité des messages d'erreur sont en fait des instructions de code de débogage glorifiées (auto) orientées programmeur.
Écrire des messages d'erreur orientés utilisateur signifie savoir qui est votre utilisateur et anticiper ce qu'il voudra savoir. Alors qu'il est en train d'écrire du code, un développeur est plus apte à écrire un message d'erreur utile pour lui-même, soit pour déboguer le code qu'il écrit actuellement, soit utile pour les cas d'utilisation connus ou prédominants.
Passer de l'écriture de code à la conception d'une partie textuelle de l'interface utilisateur (ou de l'expérience utilisateur) est un changement de contexte. Dans les applications volumineuses, telles que les applications multilingues qui pourraient signifier qu'elles sont transférées à une autre personne ou équipe (interface utilisateur, traduction) plutôt que entièrement gérées par le développeur, donc à moins que le développeur n'explique soigneusement le contexte du message, des détails importants peuvent être facilement perdu.
Bien sûr, la vérification et la vérification de la gestion des erreurs sont souvent considérées comme une priorité faible, tant que les erreurs et les exceptions sont gérées (c'est-à-dire interceptées), peu d'importance y est accordée. C'est un endroit mentalement ingrat de la base de code pour les développeurs ou QA à évaluer, car les conditions d'erreur ont souvent une connotation négative (c'est-à-dire une erreur ou un échec) qui leur est associée.
la source
Je pense que la raison en est que le rapport / traitement des erreurs se fait toujours après coup . Même lorsqu'ils ne sont pas entièrement réfléchis, ils sont pour la plupart des citoyens de seconde classe dans la conception globale.
Les logiciels modernes se composent généralement de plusieurs couches. Lorsque votre logique de rapport d'erreurs est établie à la hâte sans trop réfléchir, il est souvent difficile de rassembler toutes les informations nécessaires pour présenter des messages d'erreur utiles.
Par exemple, l'erreur est interceptée dans le serveur principal, mais elle a besoin de certaines informations des couches supérieures pour composer un message d'erreur complet. La plupart des bons messages d'erreur nécessitent des informations provenant de presque toutes les couches (pour nous donner une vue complète de ce qui s'est passé dans le système). Le message d'erreur idéal ressemblerait à "OK, nous avons d'abord reçu une chaîne, puis elle est passée à travers l'analyseur qui a donné quelque chose de drôle, vous voudrez peut-être y regarder. Quoi qu'il en soit, la chose a été transmise plus bas ..."
Le faire nécessiterait souvent un couplage inutile si le mécanisme de rapport d'erreurs n'était pas un citoyen de première classe pendant la phase de conception. Je suppose que la plupart des gens trouvent que trop de travail à faire pour quelque chose qui ne semble pas impressionnant (qui aime dire "Voir? Mon programme s'est écrasé et le message d'erreur est utile!").
la source