Comment dois-je re-raise un Delphi exception après l'enregistrement?
Connaissez-vous un moyen de piéger, de journal, et re-raise exception dans le code Delphi?
Un exemple simple:
procedure TForm3.Button1Click(Sender: TObject);
begin
try
raise Exception.Create('Bum');
except
on E: Exception do
begin
MyHandleException(E);
end;
end;
end;
procedure TForm3.MyHandleException(AException: Exception);
begin
ShowMessage(AException.Message);
LogThis(AException.Message);
// raise AException; - this will access violate
end;
J'ai donc besoin de la relancer dans le bloc except mais je me demandais si il ya une meilleure façon d'écrire ma propre méthode pour gérer et (dans certaines conditions) à re-lever des exceptions.
- Viens de re-lever de la manière habituelle. Il maintient votre code d'auto-documentation et de ne pas gâcher la trace de la pile.
- yep j'ai vraiment envie de préserver la pile!
- Si c'est la journalisation des exceptions que vous êtes après, vous devriez jeter un oeil à madExcept, EurekaLog et/ou Jedi. Ont chacun une meilleure gestion de l'enregistrement d'exception que vous pourriez jamais rêver de faire vous-même.
- Oui je sais les outils, je préfère EurekaLog, mais il n'est pas à moi de les utiliser et comment les utiliser ceux de l'outil avec les clients .. donc je fais ce que je peux 🙂
- Les Exceptions sont un décompte de références. Le déclenchement de l'exception est décrémenté lorsque l'EXCEPTION de bloquer les sorties. ÉLEVER par lui-même w/o une instance exception incrémente le compteur de référence. SOULEVER suivie par une instance exception (par exemple, pour relever E; ) ne sera pas, d'où l'AV noté. Exception à la règle.Créer (), une exception avec les ref compter du 1er et, si cela est fait dans un bloc d'exception, n'est pas soumis à l'arbitre de compter décrémenter lorsque l'EXCEPTION de bloquer les sorties. Écrire du code où élever seul peut être appelé, de créer une nouvelle exception, ou utiliser le AcquireExceptionObject() pour incrémenter la ref nombre, comme par le ci-dessous des solutions.
Vous devez vous connecter pour publier un commentaire.
Si vous voulez relancer l'exception seulement sous certaines conditions, écrire
La suite de Craig Young post, j'ai utilisé quelque chose le long des lignes de code suivant avec succès. Vous pouvez conserver l'original de l'exception de l'emplacement à l'aide de la "au" identifiant à l'ExceptAddr fonction. L'exception d'origine type de classe et de l'information est également préservé.
Ce qui suit fonctionnera, mais n'est évidemment pas idéal pour 2 raisons:
.
Les avantages sont que vous conservez l'original de la classe d'exception, et un message (et tous les autres attributs que vous souhaitez copier).
Idéalement, vous voulez les appeler
System._RaiseAgain
, mais, hélas, ce qu'est un "compilateur-magie' de routine et ne peut être appelée que parraise;
.Vous pouvez essayer d'utiliser (système d'.pas):
ReleaseExceptionObject
est également vide. Je me demande si la documentation est correcte à propos de ce comptage de référence.Exception
est dérivé de TObject pas deTInterfacedObject
.Vous devriez être en mesure d'utiliser seulement la
Raise
commande par lui-même à re-lever l'exception:raise
dans une procédure appelée dans laexcept
bloc, qui ne fonctionne pas. Leraise
doit être exactement dans leexcept
bloc. Si vous écrivezraise AException
dans la procédure externe, vous obtenez une violation d'accès.raise
une exception au sein de laexcept
bloc. Et apprendre qu'il n'est pas possible de le faire n'importe où ailleurs.Vieux sujet, mais, qu'en est cette solution?
Il est basé sur le premier code posté par Eduardo.
Cette façon de travailler pour moi!
J'ai réécrit ma méthode, et maintenant, la relance sera de même avant de.
Vous pourriez acquérir l'objet de l'exception avant d'appeler votre gestionnaire et de garder le gestionnaire lui-même un liner. Cependant, vous avez encore beaucoup de "Try/except/Faire/à la Fin de la charge.
Cependant, si vous ne voulez faire est de se débarrasser d'une répétition de code de gestion d'erreur dans les gestionnaires d'événements, vous pouvez essayer ceci:
Réduire votre code de gestionnaire d'événements à ceci:
Vous pouvez également faire travailler les fonctions à l'aide de fonctions paramétrées:
Et de faire ShowException retourner une valeur (agissant comme un passthru):
Ou même faire le anon procédure de toucher directement à l'extérieur de la portée de la variable(s):
Il y a quelques limitations sur l'interaction des variables à partir de l'intérieur du corps de la fonction anonyme et celles définies à l'extérieur de la portée, mais pour les cas simples comme celles-ci, vous serez plus que bien.