AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi Prozess trotz (mehrfacher) Exceptions fertig abarbeiten
Thema durchsuchen
Ansicht
Themen-Optionen

Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

Ein Thema von himitsu · begonnen am 21. Nov 2009 · letzter Beitrag vom 22. Nov 2009
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 21. Nov 2009, 19:45
Manchmal möchte man etwas trotz Fehler/Exceptions fertig durcharbeiten lassen...

Nun gibt es da mehere Wege:

[*] der böse Weg = einfach den/die Fehler ignorieren
ich glaub hier sind wir und einige, daß man sowas nicht macht.
Delphi-Quellcode:
var
  i: Integer;
begin
  for i := 1 to 5 do
    try
      // ...
    except
    end;
Stand selber grad vor diesem Problem, denn in einer Schleife müssen unbedingt alle Werte abgearbeitet werden,
aber dennoch sollte die Exception nicht verschwinden.

Da es sich hier nur um ein Zusatzmodul (himXML ) handelt
und im aufrufenden Code eine etwaige Exception dennoch ankommen soll/muß,
ist schonmal klar, daß der "böse Weg" absolut nicht in Frage kommt.

Ich war schon kurz davor hier zu fragen, was andere da machen würden,
aber wärend ich den Beitrag schrieb, da fiehl mir grade noch so ein Tipp ein, welchen mir her jemand vor 'ner Weile mal gegeben hatte ... Delphi-Referenz durchsuchenAcquireExceptionObject.


[*] also würde man es sich merken, ob eine Exception auftrat und diese später behandeln
nur blöde, daß hier keine mehr weiß, was mal war
Delphi-Quellcode:
var
  i: Integer;
  Fehler: Boolean;
begin
  Fehler := False;
  for i := 1 to 5 do
    try
      // ...
    except
      Fehler := True;
    end;
  if Fehler Then
    Raise Exception.Create('Irgendein Fehler ist aufgetreten, '
      + 'aber ich weiß nicht mehr welcher ._.');
[*] also noch mehr merken
hier hätten wir zwar den Text, aber für eine weitere Fehlerbehandlung ist nun die ursprüngliche Exception selber futsch
Delphi-Quellcode:
var
  i: Integer;
  Fehler: String;
begin
  Fehler := '';
  for i := 1 to 5 do
    try
      // ...
    except
      on e: Exception do
        Fehler := e.Message;
    end;
  if Fehler <> 'Then
    Raise Exception.Create(Fehler);
[*] warum dann nicht gleich alles merken?
Delphi-Quellcode:
var
  SavedExcept: Exception;
  i: Integer;
begin
  SavedExcept := nil;
  try
    for i := 1 to 5 do
      try
        // ...
      except
        if not Assigned(SavedExcept) then
          SavedExcept := AcquireExceptionObject;
      end;
  finally
    if Assigned(SavedExcept) then
      raise SavedExcept;
  end;
end;
Hier wäre es dann so, wie gewollt.

Die komplette Exception bleibt erhalten, also samt Message und Exception-Klasse.



hier nochmal ein Beispiel
Delphi-Quellcode:
procedure Test;
var
  SavedExcept: Exception;
  i: Integer;
begin
  SavedExcept := nil;
  try
    for i := 1 to 5 do
      try
        // ...
        
        if i in [2..4] then
          raise Exception.CreateFmt('Durchlauf %d', [i]);

        // ...
      except
        if not Assigned(SavedExcept) then
          SavedExcept := AcquireExceptionObject;
      end;
  finally
    if Assigned(SavedExcept) then
      raise SavedExcept;
  end;
end;
Nach außen hin wäre es so, als wenn die Prozedur im 2. Durchgang abgebrochen wäre
und man erhält auch die (erste) Exception davon.
Dennoch wurde aber die Schleife noch komplett abgearbeitet.


[*] und, entsprechend eines Vorschlages, noch die "Extremvariante"
hier wird eine Liste aller Exceptions gespeichert
und nicht nur die Erste, so wie in den vorhergehenden Beispielen.
Delphi-Quellcode:
type
  EMultiException = class(Exception)
  protected
    FList: Array of Exception;
    function GetCount: Integer;
    function GetExcept(i: Integer): Exception;
  public
    constructor Create(E: Exception);
    destructor Destroy; override;
    class procedure AddLastException(var SavedExcept: Exception);
    class procedure Reraise(SavedExcept: Exception);
    property SubExceptCount: Integer read GetCount;
    property SubException[i: Integer]: Exception read GetExcept;
  end;

function EMultiException.GetCount: Integer;
begin
  Result := Length(FList);
end;

function EMultiException.GetExcept(i: Integer): Exception;
begin
  if (i >= 0) and (i < Length(FList)) then
    Result := FList[i] else Result := nil;
end;

constructor EMultiException.Create(E: Exception);
begin
  SetLength(FList, 1);
  FList[0] := E;
  Message := FList[0].Message;
  HelpContext := FList[0].HelpContext;
end;

destructor EMultiException.Destroy;
var
  i: Integer;
begin
  for i := 0 to High(FList) do FList[i].Free;
  inherited;
end;

class procedure EMultiException.AddLastException(var SavedExcept: Exception);
begin
  if not Assigned(SavedExcept) Then
    SavedExcept := AcquireExceptionObject
  else if not (SavedExcept is EMultiException) then begin
    SavedExcept := EMultiException.Create(SavedExcept);
    EMultiException.AddLastException(SavedExcept);
  end else
    with EMultiException(SavedExcept) do begin
      SetLength(FList, Length(FList) + 1);
      FList[High(FList)] := AcquireExceptionObject;
    end;
end;

class procedure EMultiException.Reraise(SavedExcept: Exception);
begin
  if Assigned(SavedExcept) then
    raise SavedExcept;
end;
verwendet wird es z.B. so
Delphi-Quellcode:
var
  SavedExcept: Exception;
  i2: Integer;
begin
  SavedExcept := nil;
  try
    for i2 := 1 to i do
      try
        // ...
      except
        EMultiException.AddLastException(SavedExcept);
      end;
  finally
    EMultiException.Reraise(SavedExcept);
  end;
end;
und noch ein kleines Beispiel:
Delphi-Quellcode:
procedure Test(i: Integer);
var
  SavedExcept: Exception;
  i2: Integer;
begin
  SavedExcept := nil;
  try
    for i2 := 1 to i do
      try
        // ...
        raise EExternalException.CreateFmt('Test %d', [i2]);
        // ...
      except
        EMultiException.AddLastException(SavedExcept);
      end;
  finally
    EMultiException.Reraise(SavedExcept);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  S: String;
begin
  try
    Test(1);
  except
    on E: Exception do
      ShowMessage(Format('%s: "%s"', [E.ClassName, E.Message]));
  end;
  try
    Test(3);
  except
    on E: EMultiException do
    begin
      S := Format('%s: "%s"'#13#10'*********************', [E.ClassName, E.Message]);
      for i := 0 to E.SubExceptCount - 1 do
        S := Format('%s'#13#10'%s: "%s"',
          [S, E.SubException[i].ClassName, E.SubException[i].Message]);
      ShowMessage(S);
    end;
    on E: Exception do
      ShowMessage(Format('%s: "%s"', [E.ClassName, E.Message]));
  end;
end;
Zitat:
---------------------------
Project1
---------------------------
EExternalException: "Test 1"
---------------------------
OK
---------------------------



---------------------------
Project1
---------------------------
EMultiException: "Test 1"
*********************
EExternalException: "Test 1"
EExternalException: "Test 2"
EExternalException: "Test 3"
---------------------------
OK
---------------------------
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 21. Nov 2009, 19:57
Als nächsten Schritt würde ich die Exceptions dann in eine Queue schreiben, damit auch wirklich keine verloren geht.
Uwe Raabe
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 21. Nov 2009, 20:06
Gut, daß mit der Queue war für mich nicht nötig, da diese Exceptionbehandlung nach Außen nicht sichtbar ist und es dort nur die "normalen" Einzelexceptions gibt ... drum reicht es, wenn die erste Exception rausgereicht wird.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 21. Nov 2009, 20:29
So ähnlich wie "Save Exceptions" in einer ForAll-Schleife bei PL/SQL. Nur da kann man am Ende auf alle Exceptions zugreifen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 21. Nov 2009, 21:31
Für Uwe wurde noch 'ne weitere Version angehängt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 22. Nov 2009, 12:06
Zitat von himitsu:
Für Uwe wurde noch 'ne weitere Version angehängt.
Uwe Raabe
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Prozess trotz (mehrfacher) Exceptions fertig abarbeiten

  Alt 22. Nov 2009, 12:32
Ich würde das ganze in eine Funktion auslagern welche keine Exception wirft sondern einen Fehlercode zurück gibt. Wenn verschiedene Fehler aufgetreten sind können mehrere Bits gesetzt werden.
Ich bin der Meinung: Wenn eine Funktion mehrere Aufgaben zusammenfasst soll sie mir auch nicht alles im einzelnen zurück geben sondern auch Fehler etc. entsprechend zusammenfassen bzw. selbständig behandeln.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  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 18:44 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