Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Programmfortsetzung nach Exception (https://www.delphipraxis.net/132985-programmfortsetzung-nach-exception.html)

Carsten1234 23. Apr 2009 06:36


Programmfortsetzung nach Exception
 
Hallo zusammen,

ich habe eine Unit, die mehrere Funktionen für die Kommunikation mit einem am PC angeschlossen Gerät beinhaltet. Zusätzlich gibt es eine "Masterfunktion" in dieser Unit, die alle Unterfunktionen nacheinander aufruft.
Tritt nun in einer dieser (Unter-)Funktionen ein Kommunikationsfehler auf, schmeisse ich eine eigene Exception. Um das ganze mal zu verdeutlichen:
Delphi-Quellcode:
function SubFct1: integer;
begin
(...)
end;

function SubFct2: integer;
begin
(...)
end;

function MasterFct: integer;
begin
  Result:= SubFct1;
  Result:= SubFct2;
end;

procedure COMErrorHandling;
begin
  raise COMException.Create(...);
end;
In der MainForm steht ferner:
Delphi-Quellcode:
procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.OnException:= AppException;
(...)
end;

procedure TMainForm.AppException(Sender: TObject; E: Exception);
begin
  if (E is COMException) then
  begin
  (...)
  end
  else
   MessageDlg('Es ist folgender Fehler aufgetreten:' +#10+#13+
               E.Message + #10+#13 +
              'Fehlertyp: '+ E.ClassName, mtError, [mbOk], 0);
end;
Das ganze funktioniert auch fast gut.
Problem: Es wird die MasterFct betreten und SubFct1 aufgerufen. Es tritt ein Kommunikationsfehler mit dem Gerät auf und es wird eine Exception geworfen. Allerdings wird nach dem Quittieren der Fehlermeldung in der MasterFct nicht mehr weiter gegangen zu SubFct2.
Frage: Warum nicht?

Dank vorab und Gruß, Carsten

hoika 23. Apr 2009 06:44

Re: Programmfortsetzung nach Exception
 
Hallo,

das musst du anders machen

Delphi-Quellcode:
function Master: X;
begin
  try
    Sub();
  except
  end;
end;

Du musst die Exception in deiner Master-Funktion abfangen,
sonst wird deiner Master "abgeräumt".


Heiko

Carsten1234 23. Apr 2009 07:01

Re: Programmfortsetzung nach Exception
 
Hallo Heiko,

Zitat:

Zitat von hoika
Du musst die Exception in deiner Master-Funktion abfangen,
sonst wird deiner Master "abgeräumt".

Du meinst so?
Delphi-Quellcode:
function MasterFct: integer;
begin
  try
    Result:= SubFct1;
    Result:= SubFct2;
  except
  end;
end;
Dann wird die Exception doch gar nicht mehr geworfen.

Gruß, Carsten

jaenicke 23. Apr 2009 07:25

Re: Programmfortsetzung nach Exception
 
Du kannst sie ja selber wieder werfen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function Zero: Integer;
  begin
    Result := 0;
  end;

  function Test1: Integer;
  begin
    Result := 10 div Zero;
  end;

  function Test2: Integer;
  begin
    Result := 20 div Zero;
  end;

  function TestX: Integer;
  begin
    try
      Result := Test1;
    except
      Result := Test2;
      raise;
    end;
    Result := Test2;
  end;

begin
  try
    ShowMessage(IntToStr(TestX));
  except
    ShowMessage('Fehler');
  end;
end;
So wird Test2 aufgerufen und dessen Exception schlägt durch, die von dem Aufruf von Test1 geht dabei verloren. Wirft Test2 keine, schlägt die von Test1 durch.

Das müsstest du eben entsprechend anpassen, aber so sollte das realisierbar sein.

Bernhard Geyer 23. Apr 2009 07:25

Re: Programmfortsetzung nach Exception
 
Zitat:

Zitat von Carsten1234
Dann wird die Exception doch gar nicht mehr geworfen.

Doch, sie wird geschmissen, jedoch von deiner Except-Behandlungroutine "still verworfen"

Wenn du schon was machen willst dann evtl. so:
Delphi-Quellcode:
function Master: X;
begin
  try
    Sub1();
  except
    HandleErrorSub1;
  end;

  try
    Sub2();
  except
    HandleErrorSub2;
  end;
end;

Carsten1234 23. Apr 2009 07:57

Re: Programmfortsetzung nach Exception
 
Beides nicht sooooo schön.
@jaenicke:
Die Kommunikationsroutinen stehe in einer eigenständigen 'einfachen' Unit ohne Formular, DataModule o.ä. und das sollte auch so bleiben.
1. weil ich die eigentlichen COM-Routinen quasi autark haben will und 2. weil die Applikation mehrsprachig sein muss, die Übersetzungen dafür jedoch in/mit der MainForm verbunden sind. Die Exception muss also von der COM-Unit "nach oben" durchgereicht und behandelt werden.

@Bernhard:
Das "Schmeissen" einer eigenen Exception soll an einem zentralen Punkt erfolgen, weil ich bei der COM-Unit von aussen nicht nur die MasterFct aufrufen kann, sondern auch die ganzen SubFct. Die MasterFct bündelt das ganze nur zu einem zentralen Aufruf beim Erstkontakt mit dem Gerät, im weiteren Programmverlauf ist es aber auch nötig, die SubFct separat aufzurufen.

Vielleicht mal so ganz pauschal, wann meine Exception geworfen werden soll.
Fall 1: Gerät antwortet nach einem Befehl vom Programm nicht in einer bestimmten Zeit => Timeout => Exception
Fall 2: Gerät antwortet nach einem Befehl vom Programm mit einem Fehlercode => Fehlercode auslesen => Exception

In einer zentralen COM-Routine, durch die alle SubFct durch müssen, wird ein entsprechender Befehl an das Gerät geschickt und in einer repeat-until Schleife wird x Sek. auf Antwort vom Gerät gewartet. Tritt einer der beiden oben genannten Fälle ein, geht es in die 'COMErrorHandling' und hier wird je nach aufgetretenem Fehlerfall eine entsprechende Exception geworfen. Tritt keiner der beiden Fälle auf, geht es zurück in die SubFct und die vom Gerät geschickten Daten werden ausgelesen&analysiert.

jaenicke 23. Apr 2009 07:59

Re: Programmfortsetzung nach Exception
 
Zitat:

Zitat von Carsten1234
Die Exception muss also von der COM-Unit "nach oben" durchgereicht und behandelt werden.

Genau das passiert doch. Durch das raise wird die Exception erneut geworden und so zwar kurzzeitig abgefangen um die zweite Methode auszuführen, dann aber wieder erneut geworfen, falls dort nicht eine weitere Exception auftritt.

Carsten1234 23. Apr 2009 09:07

Re: Programmfortsetzung nach Exception
 
Ich habe es jetzt so gelöst, dass ich im Fehlerfall via SendMessage ein selbsterstelltes ErrorRec (packed record) an die MainForm schicke, die Message in der MainForm abfange, analysiere und eine entsprechende (fremdländische) Meldung ausgebe.

Gruß, Carsten

shmia 23. Apr 2009 10:00

Re: Programmfortsetzung nach Exception
 
Zitat:

Zitat von Carsten1234
Ich habe es jetzt so gelöst, dass ich im Fehlerfall via SendMessage ein selbsterstelltes ErrorRec (packed record) an die MainForm schicke, die Message in der MainForm abfange, analysiere und eine entsprechende (fremdländische) Meldung ausgebe.

Ohje! (SCRN)
Sagt dir dein Bauchgefühl nicht, dass das nicht gut ist, was du da tust?

Deine Anwendung kommuniziert mit einem Gerät aber es existiert keine Klasse, die das Gerät abbilden würden.
Das ist der Grund dafür weshalb du Probleme hast, mit den Exceptions richtig umzugehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:34 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