2008-11-25 7 views
4

Théoriquement, l'utilisateur final ne doit jamais voir d'erreurs internes. Mais en pratique, la théorie et la pratique diffèrent. Donc, la question est de savoir quoi montrer à l'utilisateur final. Maintenant, pour l'utilisateur totalement non technique, vous voulez montrer le moins possible ("cliquez ici pour soumettre un rapport de bug" genre de choses), mais pour les utilisateurs plus avancés, ils voudront savoir s'il y a un travailler autour, si cela a été connu pendant un certain temps, etc Donc, vous voulez inclure certains sortes d'informations sur ce qui ne va pas.Marqueurs d'erreur internes

La manière classique de faire ceci est soit un assert avec un nom de fichier: numéro de ligne ou une trace de pile avec le même. Maintenant, cela est bon pour le développeur, car il le dirige droit au problème; Cependant, il présente des inconvénients significatifs pour l'utilisateur, en particulier qu'il est très énigmatique (par exemple inamical) et que les changements de code changent le message d'erreur (Google pour l'erreur ne fonctionne que pour cette version).

J'ai un programme que j'ai l'intention d'écrire où je veux résoudre ces problèmes. Ce que je veux, c'est un moyen d'attacher une identité unique à chaque affirmation de telle manière que l'édition du code autour de l'affirmation ne l'altèrera pas. (Par exemple, si je le coupe/colle dans un autre fichier, je veux que la même information soit affichée) Des idées?

Un truc que je pense est d'avoir une énumération pour les erreurs, mais comment s'assurer qu'ils ne sont jamais utilisés dans plus d'un endroit?

(Note:. Pour cette question, je suis seulement regarder les erreurs qui sont causées par des erreurs de codage non des choses qui pourraient légitimement se produire comme entrée mauvaise Otoh ces erreurs peuvent être d'un certain intérêt pour la communauté dans son ensemble. .)

(note 2: le programme en question serait une application de ligne de commande en cours d'exécution sur le système de l'utilisateur, mais encore une fois, c'est juste ma situation)

(note 3:.. la langue cible est D et I'm very willing pour plonger dans meta-programming Réponses pour d'autres langues plus que bienvenu!)

(note 4: Je souhaite explicitement NE PAS utiliser les emplacements de code réels, mais plutôt une sorte de noms symboliques pour les erreurs. En effet, si le code est modifié de quelque manière que ce soit, les emplacements des codes changent.)

Répondre

1

écrire un script pour grep votre arborescence des sources pour des utilisations de ces codes d'erreur, puis se plaindre s'il y a des doublons. Exécutez ce script dans le cadre de vos tests unitaires.

+0

Une bonne chute en arrière, mais je préfère avoir ce genre d'erreur briser la construction – BCS

+0

@BCS ou plus des commentaires. Exécuter la vérification dans le cadre de la construction au lieu d'une partie des tests unitaires: D –

2

Question intéressante. Une solution que j'ai utilisée plusieurs fois est la suivante: S'il s'agit d'une erreur fatale (des erreurs non fatales doivent permettre à l'utilisateur de corriger l'entrée, par exemple), nous générons un fichier avec beaucoup d'informations pertinentes: en-têtes, des informations de configuration interne et un backtrace complet pour le débogage ultérieur. Nous stockons ceci dans un fichier avec un nom de fichier unique généré (et avec l'heure comme préfixe).

Pour l'utilisateur, nous présentons une page qui explique qu'une erreur irrécupérable s'est produite, et demande qu'ils incluent le nom de fichier comme référence s'ils souhaitent signaler le bogue. Beaucoup plus facile à déboguer avec toutes ces informations dans le contexte de la requête incriminée.

En PHP, la fonction debug_backtrace() est très utile pour cela. Je suis sûr qu'il y a un équivalent pour votre plate-forme.

Rappelez-vous aussi d'envoyer des en-têtes pertinentes http: Probablement: HTTP/1.1 500 Erreur serveur interne

Étant donné un format sensible du fichier de rapport d'erreur, il est également possible d'analyser les erreurs que les utilisateurs ne sont pas signalés.

+0

De plus, considérer les choses comme un enregistreur en mémoire qui va dans ce fichier. –

+0

Malheureusement, je ne dispose pas d'un système de trace dans la langue :( – BCS

1

Je ne sais rien au sujet de votre langue cible, mais cela est une question intéressante que j'ai réfléchi à et je voulais ajouter mes deux cents. Mon sentiment a toujours été que les messages pour les erreurs matérielles et les erreurs internes devraient être aussi utiles que possible pour que le développeur identifie le problème & le corriger rapidement. La plupart des utilisateurs ne verront même pas ce message d'erreur, mais les utilisateurs finaux très sophistiqués (peut-être les supporteurs techniques) auront souvent une bonne idée du problème et trouveront même de nouvelles solutions en examinant des messages d'erreur très détaillés. La clé est de rendre ces messages d'erreur détaillés sans être cryptiques, et c'est plus un art qu'une science.

Un exemple d'un programme Windows qui utilise un out-of-process serveur COM. Si le programme principal essaie d'instancier un objet à partir du serveur COM et échoue avec le message d'erreur:

« AVERTISSEMENT: Impossible d'instancier UtilityObject: erreur « Classe non inscrit » dans « CoCreateInstance » »

99% des utilisateurs verra cela et penser qu'il est écrit en grec. Une personne de support technique peut rapidement réaliser qu'elle a besoin de réenregistrer le serveur COM. Et le développeur saura exactement ce qui s'est mal passé. Pour associer certaines informations contextuelles à l'assertion, dans mon code C++, j'utilise souvent une simple chaîne avec le nom de la méthode, ou quelque chose d'autre qui indique clairement où l'erreur s'est produite (je m'excuse d'avoir répondu une langue que vous n'avez pas demandé au sujet):

int someFunction() 
{ 
    static const std::string loc = "someFunction"; 
    : : 
    if(somethingWentWrong) 
    { 
    WarningMessage(loc.c_str(), "Unable to Instantiate UtilityObject: Error 'Class Not 
    Registered' in 'CoCreateInstance); 
    } 
} 

... qui génère:

AVERTISSEMENT [someFunction]: Impossible de Instantiate UtilityObject: erreur 'classe non enregistrée' dans « CoCreateInstance

+0

Excellents points! – BCS