Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi try ... except (https://www.delphipraxis.net/139523-try-except.html)

Counter909 30. Aug 2009 21:18


try ... except
 
Hallo,


vllt eine blöde Frage, werdet ihr bestimmt auch sofort wissen, aber i-wie bin ich gerade daüfr zu blöd..

Ich möchte eine bestimmte Datei laden (zum Beispiel: C:/Programme/Delphi/test.txt)


So, wenn diese Datei nicht existiert, kommt natürlich ein dicker Fehler, sodass das Programm dann stoppt und beendet wird, weil er die Datei nicht finden kann. Deshalb gibt es doch die

Try..except Anweisung oder ? in der try routine wird der Risikobereich verwertet und falls dort ein Fehler auftritt automatisch an except weitergegeben?

nur wenn ich dann

Delphi-Quellcode:
try
 s1.loadfromfile('C:/Programme/Delphi/test.txt')
 s1.free
except
 showmessage('Die Datei ist nicht vorhanden!')
end;
mache, dann kommt immer der Fehler, dass er die Datei nicht findet und es Programm "stürzt" sozusagen ab


mfg
counter

haentschman 30. Aug 2009 21:23

Re: try ... except
 
Hallo :hi:

wenn du dein Programm aus der IDE startest bekommst du immer die Meldung angezeigt. Auch mit try/except. Starte mal das Programm ohne die IDE und du wirst deine eigene Message sehen. :P

jaenicke 30. Aug 2009 21:23

Re: try ... except
 
Erstens wirkt try..except standardmäßig nur außerhalb von Delphi, wenn du das Programm also von Delphi aus ausführst, dann stoppt das Programm trotzdem.

Zweitens solltest du lieber FileExists benutzen um vorher zu schauen, ob die Datei existiert.

Und drittens ist unter Windows das Pfadtrennzeichen \ und nicht / wie du es benutzt hast...

Counter909 30. Aug 2009 21:32

Re: try ... except
 
Fileexists war wohl der springende Punkt und hat auch gleich geholfen :-) jetzt funktioniert alles. Man kann es auch imemr kompliziert wollen :D


Besten Dank jaenicke&haentschman

himitsu 30. Aug 2009 21:45

Re: try ... except
 
trotz FileExists, solltest du eine Fehlerbehandlhng machen, denn es könnten auch noch Zugriffsfehler auftreten.
z.B. Datei ist gesperrt (fehlende Zugriffsrechte oder sie ist bereits ohne passende Sharingrechte geöfnet)


Try-Except wirkt auch innerhalb der IDE bzw. des Debuggers,
nur daß der Debugger die Exceptions dennoch anzeigt, damit der Programmierer mitbekommt, wenn etwas nicht stimmt.
> diese Debugger-Exceptions lassen sich in den Projektoptionen auch abschalten

Dann gehört sl.Free nicht in das Try-Except hinein, denn was passiert, wenn bei LoadFromFile die bearbeitung abgebrochen und an den Except-Bock abgegeben wird?
Genau, sl.Free wird nicht aufgerufen und das Objekt auch nicht freigegeben!

Eigentlich gehört hier noch ein Try-Finally drumrum
Delphi-Quellcode:
sl := TStringList.Create;
try
  // ... mach etwas ...
finally
  sl.Free;
end;
also
Delphi-Quellcode:
sl := TStringList.Create;
try
  try
    s1.loadfromfile('C:/Programme/Delphi/test.txt');
  except
    showmessage('Fehler beim Lesen!');
  end;
finally
  sl.Free;
end;
Aber da Try-Except die Bearbeitung fortestzt und zwischen .Create und .Free nur das Try Except(plus dessen Inhalt) liegt, könnte man Try-Finally auch mal ausnahmsweise weglassen
Delphi-Quellcode:
sl := TStringList.Create;
try
  s1.loadfromfile('C:/Programme/Delphi/test.txt')
except
  showmessage('Die Datei ist nicht vorhanden!')
end;
s1.free;

sx2008 31. Aug 2009 00:56

Re: try ... except
 
Bitte kein ShowMessage verwenden um Exceptions anzuzeigen.
Solle dies in einer Schleife vorkommen, die >20 Durchläufe hat, dann klickt man sich die Finger wund.
Es ist wirklich eine Unsitte bei Exceptions die Procedure ShowMessage zu verwenden.

Beispiel Webservice: ich will die Exception nicht auf dem Server angezeigt haben,
sondern die Exception muss aufsteigen im Code.
Weit oben sitzt dann ein Exceptionhandler, der die Exception a). mitloggt und b).
eine entsprechende XML/HTML-Seite mit der Meldung aufbereitet und dem Client präsentiert.

Hier ist ein Beispielcode, wie man Exceptions richtig behandelt:
Delphi-Quellcode:
filename := 'C:/Programme/Delphi/test.txt';
sl := TStringList.Create;
try
  try
    sl.loadfromfile(filename);
  except
    on E:Exception do
    begin
      E.Message := Format('Datei <%s> kann nicht geladen werden.'#13#10, [filename])+
        E.Message; // orginale Meldung bleibt erhalten
      raise;
  end;
finally
  sl.Free;
end;
Angenommen, der Benutzer hat kein Zugriff auf die Datei.
Dann bekommt er folgende Meldung präsentiert:
Code:
Datei <C:/Programme/Delphi/test.txt> kann nicht geladen werden.
Zugriff verweigert.
Das ist eine Meldung, mit der man wirklich etwas anfangen kann.
Dagegen wären die Meldungen
Code:
Die Datei ist nicht vorhanden!
oder
Code:
Fehler beim Lesen!
eher falsch bis nutzlos.
Bei einem kleinen Programm ist das nicht so schlimm, aber wenn ein Programm
mit dutzenden Formularen und zig Dateien meldet "Die Datei ist nicht vorhanden!"
dann wird der Benutzer mit Sicherheit seinen Kopf gegen die Wand hauen. :wall:


Hier nochmal die goldenen Regeln zum Behandeln von Exceptions:
1.) kein ShowMessage oder irgendetwas, das den Programmablauf aufhält einsetzen
2.) Informations Anreicherung:
wenn ich die Exception nicht selbst behandeln kann, so kann ich zumindest
die Meldung um sinnvolle Information erweitern und dann die Exception aufsteigen lassen.
Beispiel: ich lese eine Datei Zeile für Zeile und interpretiere die Daten.
In der For-Schleife sollte dann ein Exceptionhandler sitzen,
der die Fehlermeldung um "Fehler Verarbeiten der bla-bla Daten. (Zeile %d)" erweitert.
3.) keine Unterdrückung von Information
die orginale Meldung muss immer erhalten bleiben!
4.) wenn ich nichts beitragen kann, dann Finger weg von try..except
5.) leere except..end Blöcke sind (fast) immer ein Hinweis, dass hier etwas unsauber ist
Das Problem liegt dann zwischen try und except.

Das war jetzt fast ein Minitutorial, aber da steckt die Erfahrung von Jahren drin.
Ja und auch ich habe stundenlang meinen Sourcecode durchsucht weil ich ShowMessage innerhalb von except..end verwendet habe.
Jetzt natürlich nicht mehr.


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