[VCL] TERRORMANAGER, GEREZ FACILEMENT VOS MESSAGES D'ERREUR DANS VOS PROGRAMMES

florenth - 26 mai 2006 à 21:02
 Utilisateur anonyme - 25 juil. 2006 à 10:48
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/37785-vcl-terrormanager-gerez-facilement-vos-messages-d-erreur-dans-vos-programmes

Utilisateur anonyme
25 juil. 2006 à 10:48
Alors je le répète haut et fort : :-)

Chez moi et sous D2005, la dernière version de "Terror Manager :-)" fonctionne très bien.
Surtout ne pas oublier de télécharger la dernière version de TErrorManager.

@+
Cirec
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
24 juil. 2006 à 21:40
alors je suis désolé pour ces petits probleme sous D2005 mais en meme temps ce n'est pas ma faute si borland n'a pas veillé a la compatibilitée ascendante.

voila je m'excuse quand meme, mais si une ame charitable trouve la solutions sous les version superieur a D7 ... qu'il me l'a transmette et je me ferais un plaisir de corriger ma source.
cs_mcapp Messages postés 71 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 15 décembre 2011
9 juin 2006 à 23:51
Je confirme que j'ai téléchargé la version la plus récente, puisque je l'ai téléchargée ce soir.
Je confirme aussi que j'ai voulu compiler seulement le composant TErrorManager et c'est au cours de cette tentative de compilation que j'ai eu "l'unité DesignerTypes est introuvable".

J'ai eu le même message en compilant un autre composant bouton.
Utilisateur anonyme
9 juin 2006 à 22:43
Salut,

j'avais effectivement un soucis avec la version précédante mais avec la dernière modification de F0xi tout fonctionne très bien.

As-tu bien téléchargé la dernière version ?

En premier il faut compiler et installer le composant TErrorManager et ensuite seulement compiler le projet ErrorManDemo.dpr

@+
Cirec
cs_mcapp Messages postés 71 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 15 décembre 2011
9 juin 2006 à 21:20
Bonjour, J'ai Delphi 2005 professional;
Et j'ai même constat que Cirec :
"Le curseur (toujours lors de la compilation) lui me renvoie dans le fichier DesignIntf.pas et me dit que l'unité DesignerTypes est introuvable."
Je n'ai pas compris ensuite en lisant vos commentaires si c'est "râpé" et donc si je dois abandonner !
A+
Mcapp
@ Cirec: tu rajoutes dans la classe une fonction de classe (class function) qui renvoie une instance de ta classe ou qui la crée si elle n'existe pas (on garde une référence dans une variable globale ou une eventuellement CTA (seule exception f0xi !)) et on déclenche une exception lors de l'appel au constructeur.

Ah oui, on n'oublie pas de libérer la mémoire dans une section finalize par exemple.
Par contre, pour un composant, on est obligé de faire autrement (mais comment ? ^^) car on ne peut pas supprimer le Create et puis, si on veut plusieurs compos dans la même application (mais pas la même fiche) on est bien embetés.
Utilisateur anonyme
29 mai 2006 à 22:33
Effectivement tout fonctionne très bien maintenant,

Le paquet comme la démo et sous D2005 ?

Alors, que dire ... Bon boulot, le code est propre bien structuré, (mais ça c'est normal c'est du F0xi), bravo bel exemple pour l'utilisation de TCollection et TCollectionItem.

Après avoir lu vos messages, une petite question me taraude quand même :

Comment fait on pour mettre un composant en Singleton ?

Voilà sinon je met 10/10 parce qu'on ne peut pas mettre plus :-)

@+
Cirec
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
29 mai 2006 à 10:43
salut cirec, logiquement avec cette nouvelle version tu ne devrais plus avoir de probleme.

j'ai en effet, exporter l'editeur dans une unité a part et je control la version de la RTL pour pouvoir compiler sur D5,D6,D7,D8,D2005 et D2006 ...

tout devrais aller, par contre le package ne compileras que pour D6 et D7 ... pour les autres version, installation a l'ancienne sans package.
Utilisateur anonyme
28 mai 2006 à 21:40
Salut,

et moi je viens foutre ma zone dans tout ce bohneur o_O ;)

Chez moi ça ne veux pas fonctionner ?

J'ai réussi à compiler le composant et à l'installer mais l'utilisation pose problème.

Il refuse la compilation de la démo sous prétexte qu'il ne trouve pas L'unité ErrorMan (alors que tous les chemins sont bon j'ai verifié plusieurs fois et c'est pas le premier que j'installe)

Mais le curseur (toujours lors de la compilation) lui me renvoie dans le fichier DesignIntf.pas et me dit que l'unité DesignerTypes est introuvable.

Je l'ai cherché mais sans succès ... elles est éffectivement introuvable ???

Donc voilà résultat : peut pas évaluer le code

ah oui :
je peu, parcontre, mettre un nouveau composent sur ma fiche et j'ai accsès au menu pour gerer les messages ?????
enfin bref tout fonctionne en design time

Je me dis que pour compiler le composant il a bien utilisé l'unité DesignIntf.pas et là tout c'est bien passé, alors pourquoi ???

Voilà mystères et boules de gommes ;)

Sous D2005 (ça fera plaisir à certains) (^_^) :-)

@+
Cirec
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
28 mai 2006 à 01:52
Bon travail fOxi, c'est du tout bon. Je te met un 10/10

@+
Non, je ne me ratrappe pas sur tes codes.
Je parle juste de ce qui nous interesse ^^

Si tu n'aimes pas le thon, ben écoute, tant pis. ;-)

Pour le logger, tu pourrais rajouter soit :
- Un évenenement OnLogging où chacun code cela comme il veut.
- Une propriété Published qui demanderait un descendant d'un TCustomLogger (classe de ta conception) que tu auras pourvu de méthodes abstraites ... comme ça, tu sépare vraiment les taches comme il se doit.

Perso, je préfère la 2ème mais il est vrai que la 1ère est plus facile à implémenter ...
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
27 mai 2006 à 17:29
t'as vraiment decider de parler ... a force de plus venir, tu te rattrape sur mes codes ^^

1) non pas de singleton, pour la simple et bonne raison, j'aime pas le thon.

interrogation ... mmmm ... oui ... en effet, avoir 2 ErrorManager sur la meme fiche ne serait pas utile.

le rajout d'option ? vraiment non je ne vois pas ... j'ai essayer d'en fournir un maximum deja, je ne vois pas ce qu'on pourrais lui ajouter de plus mise a part peut etre des methodes au terrormanager.

pour le logger, ce n'est pas le but, je ne veux pas imposer un modele ou un schema de log au developpeur. bien que ...

sinon ... bon ben ... voila.
Ahh non, j'ai oublié : met le en singleton, c'est plus pratique. Mais bon, là, c'est déjà parfait.
Bon, résultat du test: pas de bug trouvé.
Aller, 10/10, tu l'as mérité.

En passant, je me rends compte que tu as déjà implémenté un arret du programme en cas d'erreur critique. Mais ma remarque sur le rajout d'eventuelles options reste vraie.

Sinon, il ne te restre plus qu'a coder le "logger" et ce sera complet.
Et pourquoi pas un envoi des logs sur Internet un peu comme le fait Firefox ou les programmes Windows losqu'ils plantent ? Je sais, c'est un peu poussif, mais tant qu'a faire .. lol

++
Pfffou, ça fait un sacret paquet de lignes à lire ... ^^

Alors, pour le "raise", aucun commentaire à faire en plus.
C'est ce que je pensait. Ta classe est en fait la couche au plus haut niveau de la gestion d'erreurs. Donc, si j'ai bien compris, elle sert donc à gérer les interceptions d'excetions (qui, eux, sont générés par "raise"). Dans ce cas, tout va bien.

Pour les begin ... end , OK. Je vois qu'on est d'accord.

Par contre, pour le case ... of, je continue à dire qu'il faut faire gaffe. Même avec des types comme TMyType = (mtChoix1, mtChoix2, mtChoix3) car si on rajoute un type et qu'on oublie de mettre à jour un "case of", là, on aura droit, au choix, à soit un plantage qui n'a rien à voir avec le "case of", soit à aucune erreur mais pas le résultat escompté. Je te parle en toute connaissance de cause, ça m'est arrivé, j'ai mis plusieures aures pour cerner le problème (et encore, l'unité était assez petite).

Pour le DP, je n'y ait pas réfléchi. c'est une idée qui m'est venue en une seconde et que j'ai écrite pour m'en souvenir. lol. Mais je vais y reflechir.

Par contre, je me rends compte quej'ai oublié un bout de texte dans mon commentaire.
J'ai dit : "L'idée de faire un 'log' OU un MessageDlg() est intéréssante"
Et si on veut faire les deux ? Et si on veut rajouter une option pour quitter l'application ou n'importe quoi d'autre en plus ? Là, ça va devenir chaud à entretenir. Je pense tout de suite "Decorator" mais une fois de plus, je n'y ait pas trop reflechi.

Et, là, je lance presque un mini débat, (même si ce n'est pas mon but) : je trouve que l'utilisation des TCollection et TCollectionItem n'est pas très souple car on impose le type du TCollectionItem qui sera crée. ça enlève plein de possibilités au niveau POO et perso, je suis à la recherche d'une solution (nouveau compo personel !?) qui permettrai de maintenir une liste d'objets de types différents, (dérivant tous d'une même classe évidemment) et qu'il serait possible de remplir en design-time. Je sais, je cherche compliqué, mais en même temps, ça me frustre de ne rien trouver (à part TObjectList mais c'est pas en D-T).

<joke-of-the-century etat="delire">
Arrgh, si tu fais un système d'exploitation comme ça, ca va être super giga mega bancal :
- Compatible Win32 : Ben des bugs, y'en aura un paquet, et des virus aussi.
- Compatible linux : comme ça, on mettra 1h30 pour installer un programme et il faudra manipuler le shell et tt et tt
- Compatible Mac/OS : ça fonctionnera au ralenti sur des processeurs Intel

Et compatible .NET, tu n'y a même pas pensé !!! ^^ à prendre avec des pincettes évidemment ;-)
</joke-of-the-century>
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
27 mai 2006 à 01:20
aaaah j'en attendais pas moins de toi.

premiere reponse ce serat pour le Raise :

Raise declanche en effet une exception (classe exception) pour signaler une erreur d'execution ou meme durant la conception et aussi il faut savoir ou et quand l'utiliser.

ne crois pas que je n'y ai pas penser, au depart il y avait effectivement un type d'erreur qui declancher un Raise et c'est bien la que je me suis rendus compte de mon erreur, si je puis dire.
c'est que d'un coups, au lieu de me retrouver a l'endroit ou l'erreur avait été faite dans le code, je me suis retrouver dans le code du TErrorManager la ou le raise avait été appelé.
je me suis donc dis, que j'avais mal penser au but de mon TErrorManager.

chose que j'aurais peut etre du precisé c'est que TErrorManager n'est pas la pour declancher des erreur a notre place, c'est au developpeur d'utiliser le TErrorManager pour repondre au diverse exceptions ou notification qui vont se declancher durant l'utilisation du programme et non sa conception/elaboration.

c'est la toute la difference entre Raise et TErrorManager. TErrorManager serat donc par exemple utiliser comme cela avec les exceptions :

try
strtoint('bonjour');
except
on EConvertionError do ErrorManager1.FindAndInvoke([code erreur]);
end;

ici je prouve bien que l'utilisation de TErrorManager n'est pas faite pour la conception ou meme les tests, il serat utile pour notifier quelque chose a l'utilisateur ou pour historisé des disfonctionnement durant l'utilisation normale du programme par cet utilisateur.

donc ... pas de Raise, pas de Assert. TErrorManager viens aprés cela.

-------

je ne sais pas si le design pattern serat vraiment utile pour l'instant, bien qu'en meme temps il serait bien de pouvoir detecter les erreurs emise par un programme que l'on a conçus.
mais ... pourquoi vouloir aller si loin.
la possibilitée et donc a murement reflechir.

mais le but du manager est d'etre standalone et que chaque fiche possede son propre gestionnaire d'erreur.
maintenant rien n'empeche le developpeur de faire un gestionnaire d'erreur commun pour toute son application, et il serat egalement facile de deposer TErrorManager dans un DataModule.

mais quelque part, il faudrait que j'analyse correctement le Design pattern pour voir s'il peu s'adapter a ce cas, ce qui pour le moment me semble justement pas vraiment etre le cas, mais on a toujours plusieurs possibilitée pour resoudre un probleme (surtout en delphi) donc ... ce n'est pas exclus.
Pour l'instant je reflechis plutot a l'ecrire de deux methode pour sauver et charger une liste de TError dans le TErrorManager pour en faciliter le transport dans de nouveaux ou anciens projet et meme pour le support multilangues.

-------

pour les nombreux begin end present dans la procedure SetCode en effet ils sont inutile ... c'est un petit defaut de conception que j'ai laisser qui proviens des phase de tests du composant. Je mets toujours des begin end de cette façon si durant l'elaboration du code j'ai besoin d'ajouter des choses dans la boucle, condition ect...
le netoyage quand lui n'est pas fait systematiquement, meme si je m'efforce au maximum de fournir un code propre de tout code mort. (on trouve rarement de QDC dans mes sources ne l'as tu pas remarqué ?)

-------
remarque judicieuse pour les Case of ... mais valide je pense uniquement sur des valeurs ordinale. vus qu'ici mes types sont tous definit a l'avance et je doute que quelqu'un qui voudrais ajouter des types ne pense pas a ajouter l'implementation de ces types dans les methode.
ce serait en effet tout autre avec des valeurs dont justement la valeurs ne serait pas connue d'avance et pourrais etre hors interval ...
pas le cas ici.
et au pire, le developpeur aurat une erreur durant la conception qui pourrat resoudre trés vite.
mais je prend note et vais effectuer des tests dans ce sens.

-------

dans FindAndInvoke si aucun code erreur ne correspond a celui demander alors on retourne False.
je penser que ce serait suffisant mais ta remarque semble me prouver le contraire.

peut etre vais-ja alors definir l'erreur 1 (unknow error) comme erreur a declancher par defaut si c'est le cas ou alors balancer a juste titre un raise sur Code erreur inexistant.

pour Invoke il en est tout autre vus que c'est delphi qui vas nous transmettre une erreur d'indice hors limite. probleme resolus. ^^

-------

pour l'instant comme tu peu le constater, TErrorManager ne mache qu'une partie du travail du developpeur ... j'en attendais pas moins dans une version 1.2 qui a moins d'un mois d'existance.

d'un point de vue ludique, mon but etait de me baser sur les TCollection pour fournir un exemple simple mais a la fois utile et original pour les debutant souhaitant voir comment utiliser TCollection et TCollectionItem qui sont un peu laisser de coter par beaucoup qui prefere deriver des TPaintBox, TPanel et autre composants lourdingue.

-------

donc pour le moment, je note avec interet toute tes petites remarques, l'avis exterieur est toujours bon a prendre, même les questions les plus idiotes ont autant d'interet que les questions importante, car a force de penser trop propre on n'a plus la logique moisie d'un debutant qui comprend rien et donc qui vas forcement poser des questions betes mais qui revele des cas auquels ont avait pas penser.

mais bon, c'est tout moi ça, faire un compo claire et limpide pour tous ... quel utopiste je fais.
^^

en tout cas merci pour tes compliments et c'est bien ce genre de chose qui me donne gout a la programmation et de toujours avoir envis d'aller plus loin.

[mode best of the best]
aller Nix, passe moi les id du FTP je vais debugé ton merdier d'asp en 5 minutes ^^
best of the best

hihi

tiens moi au courrant de tes tests.

[mode caprice]
et je veux aussi l'avis de tout les grand noms de delphifr, delphiprog, grandvizir, kenavo, jlen, japee, cirec, francky, ect... ect... j'en oublis mais bon desolé ...
caprice

[mode joke of the century]
demain je poste un systeme d'exploitation compatible win32, win64, linux, bsd et mac/os ...
vous me direz ce que vous en pensez ...
joke of the century

bon la c'etait histoire de parler... huhuhu
Bon, vu la qualité du code (je l'ai lu mais pas encore testé) je me sens obligé de mettre mes traditionnelles (quoique rares en ce moment, ndlr) petites remarques.
Alors voila, d'emblée je trouve que l'idée de faire un composant de gestion d'erreurs est excellente. Sa réalisaiton l'est aussi, mais j'en parlerai plus tard.
Il est vraiment nécéssaire de gérer les erreurs pour éviter qu'elles prolifèrent (ça se reproduit vite en plus ... ^^) et que tout le projet devienne bancal. La solution que propose f0xi est donc un moyen facile qui permet de gérer ce genre de petits "désagréments" tout en restant assez souple.

L'idée de faire un 'log' OU un MessageDlg() est intéréssante. Dans ce cas là, j'aurais utilisé le design pattern "stratégie" (voir le code de Delphiprog à ce sujet) mais c'est vrai que je ne sais pas si ce serait une bonne idée, ni trop comment le mettre en place (en même temps, je n'ai carrément pas réfléchi). Je le dis quand même au cas où ça en inspirerait certains à trouver une réponse.

Par contre, mais c'est peut être ton but, je trouve dommage de ne pas se servir des objets d'erreurs prédéfinis dans Delphi, ni de la commande "raise". Je trouve ce dernier oubli, si je peux dire, assez important car on continue l'execution du programme malgré l'erreur là où la commande "raise" l'aurait interrompu. C'est dommage, d'autant que ça aurait pu donner quelque chose d'intéréssant à exploiter ...
Mais après, j'imagine que tu as fait des choix judicieux et tu propose évidemment une solution adaptée à tes besoins, j'en suis conscient.

Maintenant, place à la réalisation, très soignée, on voit que tu as de l'expérience (pour ceux qui ne le savaient pas ^^)

Alors, niveau reamrques, toujours pareil, quelques détails:
- Tu n'es pas obligé de multiplier les "begin ... end" dans tes conditions (voir TError.SetCode) ça alourdit le code (mais pas la vitesse heuseusement) pour rien.
- Quand tu fais un "case ... of", prévois toujours le "else" au cas où la valeur attendue n'est pas correcte. Ca évite des erreurs et des bugs, surtout que c'est le but de ce code non ?? :-)
- Toujours dans TError.SetCode, j'aurais mis un déclenchement d'exeption au lieu du MessageDlg()
- Et dans TErrorManager, tu prévois quoi si ErrorCode ne correspond à aucun code d'erreur ? Il faudrait mettre une erreur de déclenchement d'erreur !!!

Ah lala ce cher f0xi, toujours en quète de performances et de tout.
C'est ça que j'appelle un vrai programmeur, pas quelqu'un qui "bidouille" et qui est fier de quelque chose de bancal.

Pour toutes ces raisons, je dis bravo.
Je vais de ce pas tester ton code et si demain, tu n'as pas de commentaires de moi ou si ta note est de 10/10, c'est qu'il n'y a pas de bug. ;-)

Bonne prog'
Florent
Rejoignez-nous