![]() |
Delphi-Version: 5
for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Ist hier wieder dunkle Compiler-Magic am Werk? Konstruierter Fall: Ich habe den Fall dass eine Methode entweder eine
Delphi-Quellcode:
wirft oder eine
EProgrammerNotFound
Delphi-Quellcode:
mit einem Sack an Exceptions da drin.
EAggregateException
Wenn ich nur EProgrammerNotFound-Exceptions bekomme ist alles in Butter und kann die behandeln. Ist noch etwas anderes dabei möchte ich die Exception weiter nach oben geben. Es sieht so aus:
Delphi-Quellcode:
uses System.SysUtils, System.Threading
Delphi-Quellcode:
Das klappt nur in der Theorie, denn der Compiler streicht das
procedure p();
var ex: Exception; begin try // do something amazing except on EProgrammerNotFound do findNewProgrammer(); on e: EAggregateException do begin for ex in e do if (not (ex is EProgrammerNotFound)) then raise; // E2145 findNewProgrammer(); end; else raise; end; end;
Delphi-Quellcode:
an und meint:
raise
![]() Schreibe ich es hingegen um dass statt einem for..in ein klassisches for..x..to..y zum Einsatz kommt hat niemand etwas dagegen:
Delphi-Quellcode:
procedure p();
var ex: Exception; exIndex: NativeInt; begin try // do something amazing except on EProgrammerNotFound do findNewProgrammer(); on e: EAggregateException do begin for exIndex := 0 to Pred(e.Count) do if (not (e.InnerExceptions[exIndex] is EProgrammerNotFound)) then raise; findNewProgrammer(); end; else raise; end; end; Warum ist das so? |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Fixed!
Delphi-Quellcode:
program Project5;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Threading; procedure findNewProgrammer; begin Writeln('Can not find anyone!'); end; procedure p(); var ex: Exception; begin try raise EProgrammerNotFound.Create('FooBar'); except on E: EProgrammerNotFound do begin findNewProgrammer(); end; on E: EAggregateException do begin for ex in E do begin if (not(ex is EProgrammerNotFound)) then begin raise ex; // Solved: E2145 end; end; findNewProgrammer(); end; else raise end; end; begin try p; { TODO -oUser -cConsole Main : Insert code here } except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); end; end; Readln; end. |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Müsste das dann nicht
Delphi-Quellcode:
heißen? Sonst fallen ja die anderen Exceptions im Aggregat unter den Tisch.
raise E
Delphi-Quellcode:
if (not(ex is EProgrammerNotFound)) then
begin raise E; // Solved: E2145 end; |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Alles klar, man muss es explizit angeben.
Und richtig, wenn schon, dann würde ich die gesamte EAggregateException und nicht eine einzelne aus dem Sack raisen wollen. Danke an alle! :thumb: |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Zitat:
Wenn du eine Exception reraisest, welche noch bei der Exceptionbehandlung Registriert ist, dann knallte es immer.
Delphi-Quellcode:
except
on E: ... do raise; end;
Delphi-Quellcode:
except
on E: ... do raise E; << hier knallte es dann beim END, Freigabe von "internen" E und später wieder auf das neue "E" zugreigen, was aber das Selbe ist end;
Delphi-Quellcode:
except
on E: ... do raise Exception(AcquireExceptionObject); << Deregistrieren und dann das abgelöste Exception-Objekt wiederverwenden end; |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Stimmt, danke für die Warnung. :thumb:
Das ist nach wie vor so und natürlich absolut tödlich. Die Exception wird ja am Ende des try..except freigegeben. Im Endeffekt frage ich mich aber weiterhin weshalb es bei einem for..in angemeckert wurde und bei einem for..x..to..y nicht. |
AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Eventuell wird bei diesem FOR-IN das nach dem DO als anoyme Methode implementiert?
Nja, es ist auch sooooo schwer im RAISE auf E=Self zu prüfen, also da entweder das dann nur als RAISE zu machen oder vorher intern das AcquireExceptionObject/ReleaseExceptionObject auszuführen. Auch nervt es, dass die "IMMER" die SystemException auslösen, und das ohne zu prüfen, ob jemand im Try-Except den Message-Text geändert hat, welches dabei verloren geht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz