Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi try .. except .. finally (https://www.delphipraxis.net/137104-try-except-finally.html)

jfheins 14. Jul 2009 16:25

Re: try .. except .. finally
 
Hier mal meine Meinung:

Delphi-Quellcode:
begin
   ppFile := TNativeXml.CreateName('xyz');
   try
      try
         [...]
      except
        on e: EMySQLException do
         AddLogAlert('Fehler' + ppFile.ErrorMessage);
        on e: Exception do
        begin
          AddLogAlert('Fehler' + e.ErrorMessage);
          raise;
        end;
      end;
   finally
      ppFile.Free;
   end;
end;
:arrow: In so einem Fall braucht man das finally, da man ja Exceptions re-raisen kann ("Soll sich doch wer anderes damit rumschlagen")
:arrow: finally nach except, damit man im Except noch auf das Objekt zugreifen kann (und evtl. Infos heraauszuholen

mjustin 14. Jul 2009 16:29

Re: try .. except .. finally
 
Zitat:

Zitat von Surrounder
Dass es so richtig ist weiss ich, es funktionier ja auch. Ich wollte ja wissen warum es nicht wie folgt geht:

Delphi-Quellcode:
begin
   ppFile := TNativeXml.CreateName('xyz');
   try
         [...]
   except
         AddLogAlert( 'Fehler' );
   finally
      ppFile.Free;
   end;
end;

Weil es dann fast wie Java oder C# aussehen würde? ;)

Ehrlich gesagt, fände ich es auch praktisch und lesbarer. Die Reihenfolge (erst except, dann finally) würde man nicht versehentlich verdrehen. Und wenn der Bereich Exceptionbehandlung eine Vereinfachung erhält, werden mehr Entwickler auf dieses Sprachfeature aufmerksam. Viele Entwickler nutzen Exceptions nicht und benutzen Returncodes zur Fehlerbehandlung (if MyFileSize < 0 then IrgendwasSeltsamesIstGeschehen).

Cheers,

angos 14. Jul 2009 16:37

Re: try .. except .. finally
 
Hi,


Zitat:

Zitat von Muetze1
Zitat:

Zitat von angos
So herum ist es richtig.

Wieso sollte? Wer sagt dir das? [...]


und später schreibst du:
Zitat:

Zitat von Muetze1
Der Fehler das Create in das try zu schieben wird oft und gerne gemacht.

Und exakt genau das wollte ich mit dem "So herum ist es richtig." ausdrücken. Er hat nämlich das Create in das try gesetzt und genau das habe ich an dem Source angepasst ;)

Grüße
Ansgar

Christian Seehase 14. Jul 2009 17:22

Re: try .. except .. finally
 
Moin Zusammen,

um es mal allgemein zu schreiben (wenn man denn einen try/except-Block braucht:

Delphi-Quellcode:
try
  <Resource belegen>
  try
    <Mit der Resource arbeiten>
  finally
    <Resource freigeben>
  end;
except
  <Ausnahme behandeln>
end;
Da es in dem konkreten Fall darum geht, dass eine Datei evtl. gesperrt ist, wäre es allerdings besser dies zu prüfen (z.B. durch den Versuch diese mit CreateFile exklusiv zu öffnen), und den Programmablauf an das Ergebnis der Prüfung anzupassen.
Mit try/except sollte man nur dann arbeiten, wenn es wirklich nicht anders geht.

Muetze1 14. Jul 2009 17:40

Re: try .. except .. finally
 
@angos: Sorry, dann hatte ich das falsch verstanden, ich hatte das "richtig herum" auf die Verschachtelung except/finally bezogen.

Zitat:

Zitat von Christian Seehase
Mit try/except sollte man nur dann arbeiten, wenn es wirklich nicht anders geht.

Warum? Ich hätte hier auch gerne eine Begründung zu dieser Aussage.

mjustin 14. Jul 2009 18:07

Re: try .. except .. finally
 
Zitat:

Zitat von Christian Seehase
Moin Zusammen,

um es mal allgemein zu schreiben (wenn man denn einen try/except-Block braucht:

Delphi-Quellcode:
try
  <Resource belegen>
  try
    <Mit der Resource arbeiten>
  finally
    <Resource freigeben>
  end;
except
  <Ausnahme behandeln>
end;

Das finally würde ich ans Ende setzen. Kleines Praxisbeispiel, Preisfrage: wird der Fehlerdialog angezeigt?

Delphi-Quellcode:
var
  SL: TStrings;
  S: string;
begin

try
  // Resource belegen
  SL := TStringlist.Create;
  try
    // Mit der Resource arbeiten
    S := SL[1];
  finally
    // Resource freigeben
    FreeAndNil(SL);
  end;
except
    // Ausnahme behandeln
    on E:Exception do
    begin
      ShowMessage(E.Message + Format(' - S hat %d Elemente', [SL.Count]));
    end;
end;

end;

Muetze1 14. Jul 2009 18:13

Re: try .. except .. finally
 
Das Problem was hier vorliegt: Du unterscheidest nicht, welche Exception aufgetreten ist. Du gehst in deinem Except Block fest davon aus, dass es ein Bereichsfehler/Indexfehler ist. Was aber wenn der Speichermanager das Create gar nicht durchführen konnte? Dann ist deine SL Variable so oder so im Eimer, egal wie rum except und finally stehen.

Grundlegend: Ich würde niemals mit Objekten in einem Exception Abschnitt arbeiten aus dem geschützten/umfassten Codebereich. Wenn gibt es Exceptions welche zusätzliche Informationen tragen bzw. tragen können. Aber ein Zugriff auf die Objekte aus dem geschützten Bereich im Exception - Behandlungsbereich ist nicht sicherer als innerhalb des Blockes.

Eine Exception ist eine definitive Ausnahmesituation. Wenn bei dir die Küche brennt willst du dir bestimmt auch nicht vorher nochmal in Ruhe die Hände waschen bevor du dein Telefon anfässt um die Feuerwehr zu rufen - nur weil du es sonst auch immer machst (um dein Handy sauber zu halten). Wenn eine Ausnahmesituation auftritt, dann benutze verlässliche Quellen und das ist in diesem Falle die Exception selbst.

Zitat:

Zitat von mjustin
Preisfrage: wird der Fehlerdialog angezeigt?

Antwort D der 3 möglichen: Der Code geht so nicht durch das QM und wird dir um die Ohren gehauen.

mjustin 14. Jul 2009 18:52

Re: try .. except .. finally
 
Zitat:

Zitat von Muetze1
Wenn bei dir die Küche brennt willst du dir bestimmt auch nicht vorher nochmal in Ruhe die Hände waschen bevor du dein Telefon anfässt um die Feuerwehr zu rufen - nur weil du es sonst auch immer machst (um dein Handy sauber zu halten). Wenn eine Ausnahmesituation auftritt, dann benutze verlässliche Quellen und das ist in diesem Falle die Exception selbst.

Genau das wollte ich zeigen: die finally-Behandlung (das 'Händewaschen', um im Beispiel zu bleiben) hat den Effekt, dass wichtige Kontextinformationen verloren gehen. Genau wie Du es schreibst, soll daher die Exceptionbehandlung zuerst erfolgen. Wie soll man sonst in den Fällen wo es möglich ist, die Exception sauber zu behandeln, den aktuellen Zustand der Anwendung nutzen, wenn man sie per finally zuerst wieder initialisiert, und wie soll man sinnvolle Kontextinformationen wie z.B. Kundennummer auch protokollieren, wenn man im finally schon das Kundenobjekt entsorgt hat? Und so quasi das Handy aus dem Fenster wirft, um es vor den Flammen zu retten ;)

Ob die Reihenfolge try ... finally ... except ... end oder try ... except ... finally ... end verwendet wird, macht daher schon einen Unterschied. C# und Java zum Beispel kennen nur try catch finally. Also erst "die Feuerwehr rufen", nicht als letztes.

Christian Seehase 14. Jul 2009 18:55

Re: try .. except .. finally
 
Moin Muetze,

Zitat:

Zitat von Muetze1
Zitat:

Zitat von Christian Seehase
Mit try/except sollte man nur dann arbeiten, wenn es wirklich nicht anders geht.

Warum? Ich hätte hier auch gerne eine Begründung zu dieser Aussage.

Wie der Name schon sagt, handelt es sich hier um eine Ausnahme, demzufolge finde ich es einfach sauberer mögliche Fehlerbedingungen selber zu prüfen, als es "drauf ankommen zu lassen", und die Programmsteuerung durch Exceptions zu regeln.
Zudem dauert die Verarbeitung einer Exception IMHO relativ lange, und wenn man sich erst einmal daran gewöhnt hat alle möglichen Fehlerbedingungen nicht selber zu prüfen, könnte es sich auch negativ auf das Laufzeitverhalten auswirken.

mjustin 14. Jul 2009 19:04

Re: try .. except .. finally
 
Zitat:

Zitat von Christian Seehase
Moin Muetze,

Zitat:

Zitat von Muetze1
Zitat:

Zitat von Christian Seehase
Mit try/except sollte man nur dann arbeiten, wenn es wirklich nicht anders geht.

Warum? Ich hätte hier auch gerne eine Begründung zu dieser Aussage.

Wie der Name schon sagt, handelt es sich hier um eine Ausnahme, demzufolge finde ich es einfach sauberer mögliche Fehlerbedingungen selber zu prüfen, als es "drauf ankommen zu lassen", und die Programmsteuerung durch Exceptions zu regeln.
Zudem dauert die Verarbeitung einer Exception IMHO relativ lange, und wenn man sich erst einmal daran gewöhnt hat alle möglichen Fehlerbedingungen nicht selber zu prüfen, könnte es sich auch negativ auf das Laufzeitverhalten auswirken.

Exceptions verlangsamen ein Programm nicht, solange sie nicht ausgelöst werden. Und sie haben gegenüber klassischem Returncode-basierten Fehlerstatus-Behandlungen Vorteile. Man muss keine speziellen Returnwerte für Fehlerstati reservieren, und sie können mehr Informationen zum Fehlerkontext transportieren.

Manchmal ist eine Behandlung eines Fehlers auch nicht allgemeingültig möglich, z.B. wenn die gleiche Funktion mal in einer GUI, in einem Batchjob oder einem Webservice verwendet wird. Statt
Delphi-Quellcode:
if GUIVorhanden then Benutzerfragen ... else
kann man dann einfach die Exception werfen und die konkrete Anwendung der Funktion entscheidet, wie sie mit der Fehlersituation umgehen möchte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 Uhr.
Seite 2 von 4     12 34      

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