Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Falsche Verwendung von try...except...end (https://www.delphipraxis.net/26234-falsche-verwendung-von-try-except-end.html)

shmia 20. Jul 2004 17:15


Falsche Verwendung von try...except...end
 
Viele Programmierer verwenden try...except...end auf eine falsche Weise.
Es gibt mindestens 5 "Sünden", die man begehen kann:

Delphi-Quellcode:
// 1. Sünde
// jede Exception wird komplett verschluckt
// Niemand wird je erfahren, warum das Programm nicht funktioniert !!!
// dass die Exception.Message in der Delphi IDE angezeigt wird zählt nicht,
// denn nach Murphy treten Fehler grundsätzlich beim Endbenutzer auf
try
   MachWas;
except
end;

// 2. Sünde
// Exceptions werden abgefangen und als Returncode umgesetzt
// niemand wird je erfahren, warum eine Funktion einen Fehlercode liefert
try
   MachWas;
except
   Result := 1;  // oder auch Result := False;
end;

// 3. Sünde
// Exception wird abgefangen und mit ShowMessage eine Meldung präsentiert
// niemand wird je die wahre Ursache erfahren
// in einer Schleife können tausende Meldungen produziert werden
try
   MachWas;
except
   ShowMessage('es ist Fehler in MachWas aufgetreten');
//   ShowMessage('Es ist ein Fehler aufgetreten !'; // geht's noch genauer ??
   Exit;
end;

// 3. Sünde B
// Manchmal führt die Meldung des Programmierers total in die falsche Richtung
try
   liste.LoadFromFile('C:\autoexec.bat');
   liste.Add(...)
   ....
   liste.SaveToFile('C:\autoexec.bat');
except
   // die Meldung kann völlig falsch sein.
   // eine Exception an dieser Stelle bedeutet nicht, dass die AUTOEXEC.BAT nicht vorhanden ist
   // dann lieber eine nichtssagende Fehlermeldung, als eine Falsche
   ShowMessage('C:\AUTOEXEC.BAT nicht gefunden !');
   Exit;
end;


// 4. Sünde
// Exception wird abgefangen und die Meldung mit ShowMessage präsentiert
// die orginale Exception-Class geht verloren (ein Exception-Objekt kann auch mehr Informationen
// tragen als nur eine Message (siehe EOleException); die Infos sind verloren)
// in einer Schleife können tausende Meldungen produziert werden
// es wird zwar jetzt die richtige Meldung angezeigt, aber wenn man mit Exit zurückkehrt
// hätte man das try...except gleich weglassen können
try
   MachWas;
except
   on E:Exception do
   begin
      ShowMessage(E.Message);
      Exit;
   end;
end;

// 5. Sünde
// try...except wird verwendet, um eine Resource (Speicher, Handles,...) zu schützen
// Resourcen werden mit einem Resourceschlutzblock (try...finally) geschützt und nicht
// mit einem falsch verstandenem try...except
// in folgendem Beispiel wird try..except falsch verwendet
  sl:=TStringList.create;
  sl.add('[autorun]');
  sl.add('OPEN='+app);
  sl.add('ICON='+icon);
  if copy(destfile, length(destfile)-4, 4)<>'.inf' then destfile:=destfile+'.inf';

  try
    sl.SaveToFile(destfile);
  except
    result:=false;
  end;
  sl.free;
// Richtig wäre
  sl:=TStringList.create; // Resource belegen
  try                     // direkt danach folgt das try
    sl.add('[autorun]');  
    sl.add('OPEN='+app);
    sl.add('ICON='+icon);
    if copy(destfile, length(destfile)-4, 4)<>'.inf' then destfile:=destfile+'.inf';

    sl.SaveToFile(destfile);
  finally
    sl.Free;   // die Resource wird immer freigegeben, egal was passiert
  end;
Wenn man obige Sünden nicht begeht, wird man belohnt:
man kann z.B. Exceptions, die bis an die Oberfläche kommen automatisch in einer Log-Datei speichern
oder man kann dem Benutzer zusätzlich einen Hilfe-Button (natürlich kontextsensitiv) anbieten.
Exceptions mit Help-Button anzeigen
Man könnte die Exception-Infos auch per Email zum Programmierer schicken lassen.
("Bug-Report" per EMail)

Richtige Verwendung von try...except...end
Delphi-Quellcode:
// in folgendem Beispiel werden Daten aus einer Query gelesen
// Fehler werdem in einem Memo protokolliert und der Lesevorgang geht weiter
// es werden keine Informationen unterdrückt, sondern die Fehlermeldungen werden protokolliert
while not Query1.Eof do
begin
  try
    MachWas(Query1);
  except
    on E:Exception do
    begin
       MemoLog.Lines.Add('Fehler in MachWas');
       MemoLog.Lines.Add(E.ClassName+':'+E.Message);
       MemoLog.Lines.Add('Record: ' +IntToStr(Query1.RecNo);
    end;
   Query1.Next; // nächster Datensatz
  end;
end;

// in folgendem Beispiel wird eine Exception abgefangen mit Informationen angereichert
// und erneut ausgelöst
try
   MachWas(x, y, color);
except
   on E:Exception do  // Eception abfangen
   begin
      // mit *nützlichen Informationen* anreichern
      // die Meldung wird mehrzeilig durch #13#10
      E.Message := Format('Fehler in MachWas(%d, %d, %d)'#13#10, [x, y, color]) +
         E.Message;
      Raise;  // Erneut auslösen !
   end;
end;

// Manchmal möchte man wirklich jede Exception unterdrücken
try
   anzahl := StrToInt(EditAnzahl.Text);
except
   anzahl := 1;
end;

// hier empfiehlt es sich die Exception zu vermeiden
   if EditAnzahl.Text = '' then
     anzahl := 1
   else
   begin
     anzahl := StrToInt(EditAnzahl.Text);
   end;
// Es gibt natürlich noch elegantere Lösungen (StrToIntDefault kann sich jeder selber bauen)
  anzahl := StrToIntDefault(EditAnzahl.Text, 1);

Robert Marquardt 20. Jul 2004 18:08

Re: Falsche Verwendung von try...except...end
 
2. ist nicht per se eine Suende.
Besonders in DLLs kann es unbedingt notwendig sein Exceptions zu unterdruecken.
Das Beispiel schert sich natuerlich nicht um eine genaue Aufschluesselung der Ursache, aber das muss ja nicht immer noetig sein.

(immer diese Shreipfeler)

shmia 20. Jul 2004 18:16

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von Robert Marquardt
2. ist nicht per se eine Suende.
Besonders in DLLs kann es unbedingt notwendig sein Exceptions zu unterdruecken.
Das Beispiel schert sich natuerlich nicht um eine genaue Aufschluesselung der Ursache, aber das muss ja nicht immer noetig sein.

Ja, da muss ich dir rechtgegeben. :zwinker:
Es gibt noch eine weitere Ausnahme:
Programmcode, der von Aussen über eine Automatisierungsschnittstelle aufgerufen wird, muss spezielle Vorkehrungen
treffen und darf auch ShowMessage zum Anzeigen benutzen, falls der Client die Exception nicht anzeigen kann.

Rackergen2 20. Jul 2004 18:39

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von shmia
Delphi-Quellcode:
// 5. Sünde
// try...except wird verwendet, um eine Resource (Speicher, Handles,...) zu schützen
// Resourcen werden mit einem Resourceschlutzblock (try...finally) geschützt und nicht
// mit einem falsch verstandenem try...except
// in folgendem Beispiel wird try..except falsch verwendet
  sl:=TStringList.create;
  sl.add('[autorun]');
  sl.add('OPEN='+app);
  sl.add('ICON='+icon);
  if copy(destfile, length(destfile)-4, 4)<>'.inf' then destfile:=destfile+'.inf';

  try
    sl.SaveToFile(destfile);
  except
    result:=false;
  end;
  sl.free;

Du hast da was falsch verstanden! Das Result:=false soll einer Funktion sagen, dass das Speichern nicht erfolgreich war und nicht die Ressource schützen!

Diese Verwendung sollte keinerlei Auswirkungen auf den Schutz haben, sondern vielmehr einen Funktionswert zurückgeben...

Wenn du dich schon beschweren willst, dann schreib wenigstens die ganze Funktion auf!

Delphi-Quellcode:
function TForm1.CreateAutorunFile(app, icon, destfile: String): boolean;
var
  sl: TStringList;
begin
  result:=true; //im Grunde erfolgreich
  sl:=TStringList.create; //TStringlist erstellen
  sl.add('[autorun]'); //Zeilen schreiben
  sl.add('OPEN='+app); //-"-
  sl.add('ICON='+icon); //-"-
  if copy(destfile, length(destfile)-4, 4)<>'.inf' then destfile:=destfile+'.inf'; //im Zweifelsfall Endung anhängen

  try
    sl.SaveToFile(destfile); //Speicherversuch
  except
    result:=false; //Gescheitert? Dann false zurückgeben
  end;

  sl.free; //Ressource wieder freigeben
end;
Natürlich hätte man das Ganze durch try...finally schützen können, aber das hielt ich in dem Fall nicht für nötig! Und im Fall einer Wertezuweisung in einer Funktion ist das hier ebenso falsch, weil eine Sicherung NIE GEPLANT war...

Delphi-Quellcode:
sl:=TStringList.create; // Resource belegen
  try                     // direkt danach folgt das try
    sl.add('[autorun]');  
    sl.add('OPEN='+app);
    sl.add('ICON='+icon);
    if copy(destfile, length(destfile)-4, 4)<>'.inf' then destfile:=destfile+'.inf';
    sl.SaveToFile(destfile);
  finally
    sl.Free;   // die Resource wird immer freigegeben, egal was passiert
  end;
EDIT: Wir werden uns das mal merken und machen uns dann über dich lustig... Natürlich auch, wenn du mal vollkommen recht haben solltest! Aber diesmal: :kotz: :lol:

Kernel32.DLL 20. Jul 2004 18:46

Re: Falsche Verwendung von try...except...end
 
es gibt da noch 'ne Sünde:

Man verwendet die try-except Konstruktion in einer Schleife. Bei einer Schleife, die sehr oft durchlaufen wird, verschlingt das Rechenzeit.

Terminator 24. Jul 2004 09:52

Re: Falsche Verwendung von try...except...end
 
Hi all,


bei Delphi is mir mit als erstes aufgefallen, dass man except und finally nicht miteinander verwenden kann.
In Java bsw. können folgende Blöcke gebildet werden:

Code:
try
{
    ...
}
except
{
    ...
}
finally
{
    ...
}

Da ich auf Exceptions reagieren möchte (log diese in ne Datei), setze ich finally so gut wie gar nicht ein.
Jetzt hab ich in dem Beispiel allerdings gelesen, dass mein Ansatz eigentlich falsch ist.

Delphi-Quellcode:
TRY
    ...
    sl:=TStringList.create; // Resource belegen
    ...
EXCEPT
    on E:Exception do
    begin
        Loggen
    end;
END;
s1.Free
Frag mich nun folgendes:
1. In obigen Beispiel wird doch s1 auch IMMER freigegeben oder hab ich da nen Denkfehler?.
2. Was passiert eigentlich wenn s1 nicht freigegeben wird? Wird nur unnötig Speicher belegt bis das Programm endet?


cu
Terminator

SirThornberry 24. Jul 2004 10:01

Re: Falsche Verwendung von try...except...end
 
ich finde das erste nicht als Todsünde - Es gibt programme die sind für Leute die 0 Ahnung haben. Wenn diese User bei einem Musikprogramm alle Dateien im Ordner markieren und dem programm hinzufügen wäre es unzumutbar 20 Fehlermeldungen zu bringen weil eventuell Textdateien & Cover mit auf das Programm gedroppt wurden. Oder wenn man beim Start des programmes alle dateien aus einem dump läd und eine wechseldatenträger nicht gefunden wird kann ich nicht bei 20 000 Dateien dem Nutzer jedesmal eine Meldung bringen das die Datei nicht gefunden wurde. Da ist es nutzerfreundlicher wenn die datei einfach nicht geadded wird

tommie-lie 24. Jul 2004 11:03

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von SirThornberry
Es gibt programme die sind für Leute die 0 Ahnung haben. Wenn diese User bei einem Musikprogramm alle Dateien im Ordner markieren und dem programm hinzufügen wäre es unzumutbar 20 Fehlermeldungen zu bringen weil eventuell Textdateien & Cover mit auf das Programm gedroppt wurden.

Wenn der Anwender 0 Ahnung hat, muss der Entwickler Ahnung haben.
Hat der Entwickler 0 Ahnung, muss zwangsläufig der Anwender Ahnung haben.
In solchen Fällen versuche ich nicht einfach blind ein .jpg per Mediaplayer abzuspielen, sondern ich (als Entwickler) schaue vorher, was ich denn da für Dateien kriege (Notfalls anhand des Dateinamens). Dann gibt's keine Exceptions und ich kann selber entscheiden ob ich für jede Datei eine Meldung anzeige oder nur für die erste oder überhaupt nicht (letzteres wäre bei sowas wohl das sinnvollste).

Zitat:

Oder wenn man beim Start des programmes alle dateien aus einem dump läd und eine wechseldatenträger nicht gefunden wird kann ich nicht bei 20 000 Dateien dem Nutzer jedesmal eine Meldung bringen das die Datei nicht gefunden wurde.
Auch da ist es sinnvoller, wenn ich mich als Entwickler vorher darum kümmere, wohin ich meine Daten schreiben will, indem ich vorher schaue, ob mein Zieldatenträger existiert (genauso wie wenn ich Dateien überschreiben soll). Und 20000 Fehlermeldungen sollten bei sowas auhc nicht auftreten. Wenn ich eine Datei schon nicht schreiben kann, weil das Medium nicht vorhanden oder voll ist, werde ich wohl die 19999 weiteren in meiner Liste auch nicht schreiben können, ergo fordere ich den User auf, ein neues Medium zu mounten oder erstmal Platz auf dem bereits vorhandenen zu schaffen, und solange warte ich und versuche nicht ständig drauf zuzugreifen.

Die Liste der Sünden gilt für Entwickler mit Grips, für Anfänger sind das garantiert keine Sünden, ganz einfach weil die's nicht besser wissen und nicht die nötige Erfahrung haben.

phlux 24. Jul 2004 11:13

Re: Falsche Verwendung von try...except...end
 
Ich fand des Tut ganz okay :thumb: hat mir das Exceptionhandling etwas näher gebracht :mrgreen: (Exceptions? Brauch ich net :zwinker: )

torud 24. Mai 2006 12:01

Re: Falsche Verwendung von try...except...end
 
Ich fand das Tut auch ganz toll, denn ich bin auch so ein Schlumi, der gern mal was in einen solchen Block packt, aber nichts damit anfängt. Ich denke, das ich da demnächst mehr darauf achten werde und das war auch sicher einer der Denkansätze für das Einbringen eines solchen Threads.

smudo 24. Mai 2006 12:24

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von Terminator
Frag mich nun folgendes:
1. In obigen Beispiel wird doch s1 auch IMMER freigegeben oder hab ich da nen Denkfehler?.
2. Was passiert eigentlich wenn s1 nicht freigegeben wird? Wird nur unnötig Speicher belegt bis das Programm endet?

1.) Nein, wird nicht immer freigegeben. Nach einer Exception wird nur noch der Except-Block ausgeführt. Du musst also auch in den Except-Block das freigeben integrieren.

2.) Ja. Es wird unnötiger Speicher belegt. Und das u.U. über das Programmende hinaus

René

RavenIV 24. Mai 2006 12:35

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von Terminator

Delphi-Quellcode:
TRY
    ...
    sl:=TStringList.create; // Resource belegen
    ...
EXCEPT
    on E:Exception do
    begin
        Loggen
    end;
END;
s1.Free
Frag mich nun folgendes:
1. In obigen Beispiel wird doch s1 auch IMMER freigegeben oder hab ich da nen Denkfehler?.
2. Was passiert eigentlich wenn s1 nicht freigegeben wird? Wird nur unnötig Speicher belegt bis das Programm endet?


cu
Terminator

zu 1.
nein sl wird nicht freigegeben, weil der Ablauf in den except-Teil springt und anschliessend die procedure verlassen wird.
zu 2.
du bekommst Speicherlöcher (memory leaks), weil der Speicher belegt bleibt und nicht neu zugewiesen werden kann. Ausserdem kannst Du unerwartete Nebeneffekte bekommen, wenn Du z.B. sl neu erzeugst. Also immer schauen, dass alle mit create angelegte Objekte auch wieder ein free erfahren.

smudo 24. Mai 2006 12:39

Re: Falsche Verwendung von try...except...end
 
:bounce2: Erster !

RavenIV 24. Mai 2006 12:43

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von smudo
:bounce2: Erster !

es kam kein roter Kasten :?

himitsu 24. Mai 2006 12:54

Re: Falsche Verwendung von try...except...end
 
@Terminator
du kannst try-finally/except auch verschachteln :zwinker:

entweder erst die excption behandeln und dann freigeben
Code:
try
{
    ...
}
except
{
    ...
}
finally
{
    ...
}
=
Delphi-Quellcode:
try
  try
    ...
  except
    ...
  end;
finally
  ...
end;
oder erst freigeben und dann die Exception
Code:
try
{
    ...
}
finally
{
    ...
}
except
{
    ...
}
=
Delphi-Quellcode:
try
  try
    ...
  finally
    ...
  end;
except
  ...
end;
Aber stimmt schon ... zusammen (als ein Try-Block) hab ich's mir auch schon gewünscht :roll:

MStoll 24. Mai 2006 12:55

Re: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von smudo
1.) Nein, wird nicht immer freigegeben. Nach einer Exception wird nur noch der Except-Block ausgeführt. Du musst also auch in den Except-Block das freigeben integrieren.

Hi,

wenn nur noch der Except-Block ausgeführt werden würde, das wäre ja schrecklich. Das ist nicht so! Es kann ja nicht sein, dass man bei ner Exception keine Möglichkeit mehr hat, hinter dem Teil mit der Exception weiterzumachen.

Gruß
Michael

Sidorion 24. Mai 2006 15:58

Re: Falsche Verwendung von try...except...end
 
Dass das noch niemandem aufgefallen ist:
Zitat:

Delphi-Quellcode:
// in folgendem Beispiel werden Daten aus einer Query gelesen
// Fehler werdem in einem Memo protokolliert und der Lesevorgang geht weiter
// es werden keine Informationen unterdrückt, sondern die Fehlermeldungen werden protokolliert
while not Query1.Eof do
begin
  try
    MachWas(Query1);
  except
    on E:Exception do
    begin
       MemoLog.Lines.Add('Fehler in MachWas');
       MemoLog.Lines.Add(E.ClassName+':'+E.Message);
       MemoLog.Lines.Add('Record: ' +IntToStr(Query1.RecNo);
    end;
   Query1.Next; // nächster Datensatz
  end;
end;

Hier wird Query1.Next nur gerufem, falls es zu einer Exception gekommen ist. Sobald ein Datensatz durchläuft, wirds ne Endlosschleife. besser:
Delphi-Quellcode:
// in folgendem Beispiel werden Daten aus einer Query gelesen
// Fehler werdem in einem Memo protokolliert und der Lesevorgang geht weiter
// es werden keine Informationen unterdrückt, sondern die Fehlermeldungen werden protokolliert
while not Query1.Eof do
begin
  try
    try
      MachWas(Query1);
    except
      on E:Exception do
      begin
         MemoLog.Lines.Add('Fehler in MachWas');
         MemoLog.Lines.Add(E.ClassName+':'+E.Message);
         MemoLog.Lines.Add('Record: ' +IntToStr(Query1.RecNo);
      end;
    end;
  finally
    Query1.Next; // nächster Datensatz
  end;
end;

shmia 24. Mai 2006 16:05

Re: Falsche Verwendung von try...except...end
 
@Sidorion: da hast du natürlich Recht, aber dein Lösungsvorschlag war nicht so gut.
Delphi-Quellcode:
// in folgendem Beispiel werden Daten aus einer Query gelesen
// Fehler werdem in einem Memo protokolliert und der Lesevorgang geht weiter
// es werden keine Informationen unterdrückt, sondern die Fehlermeldungen werden protokolliert
while not Query1.Eof do
begin
  try
    MachWas(Query1);
  except
    on E:Exception do
    begin
       MemoLog.Lines.Add('Fehler in MachWas');
       MemoLog.Lines.Add(E.ClassName+':'+E.Message);
       MemoLog.Lines.Add('Record: ' +IntToStr(Query1.RecNo);
    end;
  end;
  Query1.Next; // nächster Datensatz
end;
Das Query1.Next ist nun an der richtigen Stelle; try..finally wird hier nicht benötigt.

Sidorion 24. Mai 2006 16:58

Re: Falsche Verwendung von try...except...end
 
Schon, aber Du weißt ja, wie das ist: In fünf Monaten macht da irgendwer ein raise; dran und dann wars wieder keiner ;)

altlastenverwalter 23. Aug 2010 08:34

AW: Falsche Verwendung von try...except...end
 
Die 5. Sünde ist Unfug (zumindest bei Delphi 6 - hab gerade keine andere Version parat).

Einen finally-Handler benötigt man nur, wenn man Exceptions nicht gesondert behandeln möchte.
Selbstverständlich wird nach dem Except normal weitergemacht und eben nicht die Prozedur verlassen!

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var a,b: double;
begin
 try
 b := 0;
 a := 666;
 a := 10 / b;
 except
   ShowMessage('nulldivision');
 end;
 ShowMessage(FloatToStr(a));
end;
Beide ShowMessage werden ausgeführt.

Ich weiß, dass dieser Thread alt ist, aber leider ist das der 3. Google-Treffer, wenn man nach Delphi-Exception sucht. Habe mich extra angemeldet in der Hoffnung, dass der Threadersteller seinen Eingangsbeitrag noch editieren könnte, damit nicht weiterhin diese Unwahrheit verbreitet wird.

Bernhard Geyer 23. Aug 2010 08:39

AW: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von altlastenverwalter (Beitrag 1044282)
Die 5. Sünde ist Unfug (zumindest bei Delphi 6 - hab gerade keine andere Version parat).

Einen finally-Handler benötigt man nur, wenn man Exceptions nicht gesondert behandeln möchte.
Selbstverständlich wird nach dem Except normal weitergemacht und eben nicht die Prozedur verlassen!

Ist kein Unfug. Finally ist zur Freigabe von Ressourcen zu verwenden! Es wurde auch nicht davon gesprochen das im except-Teil die Funktion verlassen wird. Wird z.B. statt einer Exption ein exit aufgerufe wird dein Code nach dem Except nicht aufgerufen, der Finally-Teil trotzdem.

himitsu 23. Aug 2010 08:53

AW: Falsche Verwendung von try...except...end
 
Und wenn in der Exception-Behandlung auch noch eine Problem auftritt, dann wird hier auch nichts mehr freigegen.

Dein ShowMessage kann auch aus verschiedenen Gründen zu einer Exception führen und dann war's das mit der Code-Ausführung danach.

(Ja, ich geb zu, daß ich diese Art der Freigabe auch an einigen Stellen einsetze, aber in diesen Fällen hatte das A) seine Gründe (vorallem um noch ein paar Millisekündchen einzusparen, bei der Masse an Ausführungen) oder einfach nur wegen des kürzeren Codes und vorallem B) wußte ich, daß es in dieser Exceptionbehandlung garantiert zu keinem Problem kommen konnte (es sei denn es gibt so masive Probleme, daß das Programm sowieso gleich komplett verreckt wird).

Aber in allen anderen Fällen kann ich ebenfalls nur die Freigabe über ein zusätzliches Try-Finally empfehlen.
Vorallem da es so auch offensichtlicher wird, daß hier immer freigegeben, bzw daß dieser Code immer ausgeführt wird.

altlastenverwalter 23. Aug 2010 09:30

AW: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1044283)
Es wurde auch nicht davon gesprochen das im except-Teil die Funktion verlassen wird.

Doch. Smudo hat genau das behauptet:

Zitat:

Zitat von smudo;
:
1.) Nein, wird nicht immer freigegeben. Nach einer Exception wird nur noch der Except-Block ausgeführt. Du musst also auch in den Except-Block das freigeben integrieren.

Zitat:

Zitat von Bernhard Geyer (Beitrag 1044283)
Wird z.B. statt einer Exption ein exit aufgerufe wird dein Code nach dem Except nicht aufgerufen, der Finally-Teil trotzdem.

Das stimmt. Exit wurde aber bisher nicht erwähnt.
Vor allem hat es nichts mehr mit Sünde 5 von shmia zu tun. Dort ERSETZT finally einfach das except und die eigentliche Fehlerbehandlung fehlt.

implementation 23. Aug 2010 11:23

AW: Falsche Verwendung von try...except...end
 
Der try-finally-Block ist ja auch nicht dazu da um Exceptions zu behandeln.
Falls im try-Block eine auftritt, bleibt sie geworfen und wird weiterhin Ebene für Ebene hochgereicht bis sie behandelt wird.
Delphi-Quellcode:
procedure Prozedur;
begin
  try
    TueWas;
  finally
    // Die Exception wird absichtlich nicht abgefangen.
    GebeResourcenFrei;
  end;
end;

...

try
  TueWas;
  Prozedur;
  TueWas;
except
  // Denn sie soll HIER behandelt werden.
  on E: EChuckNorrisIsDead do
  begin
    ...
  end;
end;
Wenn man statt dem oberen try-finally ein try-except verwendet, wird die Exception ja abgefangen.
Und das soll doch überhaupt nicht passieren.

Kieni 9. Dez 2010 14:33

AW: Falsche Verwendung von try...except...end
 
Hallo,

ich habe mal eine Frage. Ist die Verwendung von try...except im folgenden Code richtig angewandt, bzw möglich:

Code:
  If WinVer.VersionText = 'Microsoft Windows XP' then
  begin
    S:='Install .NET Framework 3.5';
    WriteLog(S);
    try
      ExecuteCommand(installDir+'\dotNet3.5.exe',SW_SHOWNORMAL,true,nil,nil);
      S:='finished at ' + DateTimeToStr(Now);
      WriteLog(S);
    except
      on E:Exception do
      begin
        Writelog('Error while installing dotNet 3.5');
        Writelog(E.ClassName+':'+E.Message);
      end;
    end;
  end;
Gruß Kieni

DeddyH 9. Dez 2010 14:40

AW: Falsche Verwendung von try...except...end
 
Das ist richtig so: wenn das ExecuteCommand fehlschlägt, dann wird der Fehler mitgeloggt.

[edit] Nachtrag: das setzt natürlich voraus, dass im Fehlerfall auch wirklich eine Exception geworfen wird ;) [/edit]

sgbSoftwareEntwickler 24. Feb 2011 08:11

AW: Falsche Verwendung von try...except...end
 
Vielen Dank für den Beitrag shmia

MephistoMyRo 24. Feb 2011 10:29

AW: Falsche Verwendung von try...except...end
 
Ich will ja nicht kleinlich sein, aber:
Delphi-Quellcode:
// in folgendem Beispiel werden Daten aus einer Query gelesen
// Fehler werdem in einem Memo protokolliert und der Lesevorgang geht weiter
// es werden keine Informationen unterdrückt, sondern die Fehlermeldungen werden protokolliert
while not Query1.Eof do
begin
  try
    MachWas(Query1);
  except
    on E:Exception do
    begin
       MemoLog.Lines.Add('Fehler in MachWas');
       MemoLog.Lines.Add(E.ClassName+':'+E.Message);
       MemoLog.Lines.Add('Record: ' +IntToStr(Query1.RecNo);
    end;
   Query1.Next; // nächster Datensatz
  end;
end;
Wenn
Delphi-Quellcode:
MachWas(Query1)
keine Exception auslöst, dann wird das hier ne Endlos-Schleife...

Delphi-Quellcode:
Query1.Next; // nächster Datensatz
müsste ein
Delphi-Quellcode:
end
weiter. Bitte korregieren oder ich hab da etwas falsch verstanden.

DeddyH 24. Feb 2011 10:34

AW: Falsche Verwendung von try...except...end
 
Wie kommst Du darauf?

Neutral General 24. Feb 2011 10:35

AW: Falsche Verwendung von try...except...end
 
Zitat:

Zitat von DeddyH (Beitrag 1084021)
Wie kommst Du darauf?

Weil das Query1.Next im except-Block steht.

DeddyH 24. Feb 2011 10:45

AW: Falsche Verwendung von try...except...end
 
Oh, stimmt, das "end" zum "try" kommt ja erst danach.


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