AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon
Thema durchsuchen
Ansicht
Themen-Optionen

for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

Ein Thema von Der schöne Günther · begonnen am 4. Jul 2018 · letzter Beitrag vom 4. Jul 2018
Antwort Antwort
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 10:58
Delphi-Version: 5
Ist hier wieder dunkle Compiler-Magic am Werk? Konstruierter Fall: Ich habe den Fall dass eine Methode entweder eine EProgrammerNotFound wirft oder eine EAggregateException mit einem Sack an Exceptions da drin.

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:

uses System.SysUtils, System.Threading
Delphi-Quellcode:
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;
Das klappt nur in der Theorie, denn der Compiler streicht das raise an und meint:

E2145 Wiederhervorrufen einer Exception ist nur im Exception-Handler möglich

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?
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 11:15
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#3

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 11:23
Müsste das dann nicht raise E heißen? Sonst fallen ja die anderen Exceptions im Aggregat unter den Tisch.
Delphi-Quellcode:
        if (not(ex is EProgrammerNotFound)) then
        begin
          raise E; // Solved: E2145
        end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 11:25
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!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 11:49
Alles klar, man muss es explizit angeben.
Dann hoffe ich die haben den anderen "Bug" behoben.

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;
$2B or not $2B
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 13:25
Stimmt, danke für die Warnung.

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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: for..in erlaubt kein "raise" im Exception-Handler, for..to hingegen schon

  Alt 4. Jul 2018, 14:15
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz