![]() |
Try Except Problem
Hallo,
ich habe folgendes Problem. Ich lade eine Datei in mein Programm, falls das schief gehen soll, soll der alte Pfad wieder gesetzt werden. Das klappt aber irgendwie nicht, wieso eigentlich?
Delphi-Quellcode:
procedure TForm1.OpenDialog1BitBtnClick(Sender: TObject);
var str: String = ''; begin str := Edit1.Caption; try if OpenDialog1.Execute then begin Edit1.Caption := OpenDialog1.FileName; end; except on E: Exception do MessageDlg('Fehler: Die Datei konnte nicht geladen werden!' + sLineBreak + sLineBreak + E.ClassName + sLineBreak + E.Message, mtError, [mbOk], 0); Edit1.Caption := str; // Hier der Fehler: Syntax error, "ON" expected but "identifier EDIT1" found end; end; Danke! |
AW: Try Except Problem
begin und end kennst Du?
|
AW: Try Except Problem
Zitat:
Delphi-Quellcode:
procedure TForm1.OpenDialog1BitBtnClick(Sender: TObject);
var str: String = ''; begin str := Edit1.Caption; try if OpenDialog1.Execute then begin Edit1.Caption := OpenDialog1.FileName; end; except on E: Exception do begin MessageDlg('Fehler: Die Datei konnte nicht geladen werden!' + sLineBreak + sLineBreak + E.ClassName + sLineBreak + E.Message, mtError, [mbOk], 0); end; Edit1.Caption := str; // Hier der Fehler: Syntax error, "ON" expected but "identifier EDIT1" found end; end; |
AW: Try Except Problem
Delphi-Quellcode:
Gruß
procedure TForm1.OpenDialog1BitBtnClick(Sender: TObject);
var str: String = ''; begin str := Edit1.Caption; try if OpenDialog1.Execute then begin Edit1.Caption := OpenDialog1.FileName; end; except on E: Exception do begin MessageDlg('Fehler: Die Datei konnte nicht geladen werden!' + sLineBreak + sLineBreak + E.ClassName + sLineBreak + E.Message, mtError, [mbOk], 0); Edit1.Caption := str; // Hier der Fehler: Syntax error, "ON" expected but "identifier EDIT1" found end; end; end; |
AW: Try Except Problem
Ah jah... alles klar! Danke!
|
AW: Try Except Problem
Man kann es sich schwer oder eben einfach machen:
Delphi-Quellcode:
procedure TForm1.OpenDialog1BitBtnClick(Sender: TObject);
begin if OpenDialog1.Execute then begin LoadFile ( OpenDialog1.Filename ); Edit1.Caption := OpenDialog1.FileName; end; end; |
AW: Try Except Problem
In dem Code gibt es eigentlich nichts zum Knallen und wenn es doch knallt, dann ist eh alles zu spät und dann hilft auch keine Exception-Behandlung mehr.
Und wenn ich mir den ersten Code so anseh:
Ergebnis siehe Zitat:
|
AW: Try Except Problem
Wenn das Laden fehlschlägt, sollte der Pfad sicherlich auch nicht angezeigt werden:
Delphi-Quellcode:
procedure TForm1.OpenDialog1BitBtnClick(Sender: TObject);
begin {$BOOLEVAL OFF} if OpenDialog1.Execute and LoadFile(OpenDialog1.Filename) then Edit1.Caption := OpenDialog1.FileName; end; |
AW: Try Except Problem
Zitat:
|
AW: Try Except Problem
Wie geht man mit Exceptions um?
Wenn man die behandeln kann, dann und nur dann nimmt man einen
Delphi-Quellcode:
. Ansonsten macht man sich das Verhalten einer Exception zunutze (alle Anweisungen danach werden nicht mehr ausgeführt):
try except
Delphi-Quellcode:
Wenn jetzt
procedure TForm1.LoadFileButtonClick( Sender : TObject );
begin if OpenDialog1.Execute then begin Memo1.LoadFromFile( OpenDialog1.Filename ); Edit1.Text := OpenDialog1.Filename; end; end;
Delphi-Quellcode:
eine Exception auslöst, dann wird
Memo1.LoadFromFile( OpenDialog1.Filename );
Delphi-Quellcode:
nicht verändert und es erscheint der Dialog mit der Fehlermeldung.
Edit1
Ist es das Verhalten, was gesucht wird? Und komisch, das bekommt man ohne diese seltsame Schnickschnack Programmierung. Und irgendwie ist es auch noch einfacher. Das Herumfuhrwerken an Exceptions und das Erstellen von Wrapper-Methoden, die im Fall der Fälle dann statt einer Exception einen bestimmten Rückgabewert liefern, führt meistens nur zu wesentlich mehr und unlesbarem Code und in 99% aller Fälle dazu, dass Programmierfehler unentdeckt bleiben. Exceptions sind nicht der Feind, aber das Abfangen ohne wirkliche Behandlung ist der erste Schritt um die Anwendung zu meinem Feind zu machen. Ja ich höre schon wieder die Stimmen "aaaaaber, ...". Natürlich kann man Exceptions abfangen, aber eben nur wenn man diese auch behandeln kann. Ohne sinnvolle Behandlung ist nur noch ein erneutes Werfen sinnvoll, wobei hier auch eine Übersetzung bzw. Umleitung auf eine eigene Exceptionklasse erfolgen kann.
Delphi-Quellcode:
MyConnection.StartTransaction;
try MyQueryA.ExecSQL; MyQueryB.ExecSQL; MyConnection.Commit; except MyConnection.Rollback; raise; end; |
AW: Try Except Problem
Zitat:
Gruß K-H |
AW: Try Except Problem
Der falsche Umgang mit Exceptions (ich bezeichne das gerne als eine lethale Exception-Phobie) führt zu den interessantesten Problemen, die nur durch aufwändigstes Debugging zu beheben sind:
Delphi-Quellcode:
Sieht doch schick aus und wir werden niemals eine Exception sehen - GottSeiDank!
function TForm1.LoadFromFile( const AFilename : string ) : Boolean;
begin try Memo1.LoadFromFile( AFilename ); Result := True; except Result := False; end; end;
Delphi-Quellcode:
Ei, was haben wir uns da eine schöne robuste KeineExceptionWerfende Funktionalität gebaut (stundenlang-auf-die-schultergeklopfe).
procedure TForm1.LoadFileButtonClick(Sender : TObject );
begin if OpenDialog1.Execute then begin if LoadFromFile( OpenDialog1.Filename ) then Edit1.Text := OpenDialog1.Filename else ShowMessage( 'Datei nicht gefunden ' + OpenDialog1.Filename ); end; end; Irgendeine Knalltüte (in 99% der Fälle, ist man das sogar selber) hat uns aber irgendwo in den Code folgende Zeile eingebaut:
Delphi-Quellcode:
Jetzt wird keine Datei mehr geladen selbst wenn es die Datei gibt und die Anwendung behauptet in der Meldung steif und fest, dass es diese Datei nicht gibt. Ich wünsche eine fröhliche Fehlersuche, wenn der Anwender mitteilt, dass keine Datei mehr geladen wird. Natürlich behaupten wir - wegen unsere unfehlbaren Methode - dass es diese Datei dann eben auch nicht gibt. Und wir testen das Laden bis zum Erbrechen und werden keinen Fehler finden und natürlich den Anweder einfach als DAU abstempeln.
procedure TForm1.SomethingSpecial;
begin // mehrere Zeilen Code Memo1 := nil; // noch mehr Zeilen Code end; Woher sollen wir denn wissen, dass dieses Verhalten nur dann auftaucht, wenn man vorher diese oder jene Funktion ausgeführt hat, die eben dieses
Delphi-Quellcode:
ausführt?
Memo1 := nil;
Ja, woher soll man das wissen? Und was ist damit?
Delphi-Quellcode:
Keine Datei gefunden -> Fehlerdialog mit EFileNotFound erscheint, Edit1 bleibt unverändert
procedure TForm1.LoadFromFile( const AFilename : string );
begin Memo1.LoadFromFile( AFilename ); end; procedure TForm1.LoadFileButtonClick(Sender : TObject ); begin if OpenDialog1.Execute then begin LoadFromFile( OpenDialog1.Filename ); Edit1.Text := OpenDialog1.Filename; end; end; Memo1 ist nil -> Fehlerdialog mit EAccessViolation erscheint, Edit1 bleibt unverändert Suchst du noch oder hast du den Fehler schon behoben ... bzw. Diskutierst du noch mit dem Anwender oder suchst du schon den Fehler ... |
AW: Try Except Problem
Zitat:
Delphi-Quellcode:
und noch beliebter ist Code ala
procedure TForm1.LoadFromFile( const AFilename : string );
begin try Memo1.LoadFromFile( AFilename ); except end; end;
Delphi-Quellcode:
try
i := StrToInt('abc'); except i := 0; end; |
AW: Try Except Problem
@himitsu
Bei so einem Code sollte einem eigentlich augenblicklich die Gicht in die Finger fahren. Mal sehen ob sich das mit einer IDE-Erweiterung realisieren lässt :mrgreen: |
AW: Try Except Problem
Zitat:
|
AW: Try Except Problem
Das sollte sowieso standardmäßig aus sein und auch besser aus bleiben.
|
AW: Try Except Problem
Naja, eher sollte diese Einstellung vor Code, die sich auf die eine oder andere Richtung darauf verlässt, grundsätzlich gesetzt werden. ;-)
|
AW: Try Except Problem
Ich würde mich bei Delphi gar nicht darauf verlassen. Sonst kommt irgendein Waldschrat mal auf die Idee, das anzuschalten und dann wundert man sich doch etwas.
Ich habe mich bei Delphi jedenfalls nie darauf verlassen. |
AW: Try Except Problem
Ich hab es aufgegeben alle "Standards" selber nochmal zu setzen.
Wenn irgendein Idiot daran rumspielt, dann hat er Pech und muß mit den Konsequenzen leben. Ich bin auch dafür, daß solche Optionen endlich mal aus den Projektoptionen raus fliegen oder es zumindestens mit mindestens 200 "Willst du das wirklich?"-Dialogen bestätigen muß. |
AW: Try Except Problem
Zitat:
|
AW: Try Except Problem
Jupp, das hab ich bei einigen Codes auch schon gemacht.
Leider gibt es IfOpt nur für die alten einbuchstabigen "+/-"-Optionen. :cry: Einfach so umschalten und danach "zurückschalten" ist einfach nur falsch, vorallem wenn man sich vorher nicht den aktuellen Zustand merkt und danach "wirklich" wiederherstellt. Leider fehlt auch noch eine Push/Pop-, bzw. Save/Restore-Möglichkeit, für die Compilerschalter. Sowas wäre ja toll,
Delphi-Quellcode:
bzw.
{$PUSH Options} // oder {$PUSH Option X}
{$X+} machwas; {$POP Options}
Delphi-Quellcode:
aber die Realität sähe etwa so aus :wall:
{$SAVEOPT X}
{$X+} machwas; {$RESTOREOPT X}
Delphi-Quellcode:
denn
{$IFOPT X+} {$DEFINE _SaveX} {$ELSE} {$UNDEF _SaveX} {$ENDIF}
{$X+} machwas; {$IFNDEF _SaveX} {$X-} {$ENDIF}
Delphi-Quellcode:
wäre halt sowas von total falsch, wenn das X vorher schon aktiviert war und es danach nicht mehr ist. :warn:
{$X+}
machwas; {$X-} |
AW: Try Except Problem
Zitat:
Delphi-Quellcode:
Die Includes müsste man nur einmal schreiben :mrgreen:
{$I StoreOptions}
{$X+} // Zeug {$I LoadOptions} Aber stimmt schon, ein richtiger eingebauter Optionsstack wäre natürlich besser. |
AW: Try Except Problem
Zitat:
Aber welche anderen Einstellungen bringen denn die Logik potentiell so durcheinander, dass es tragisch wäre, wenn die anders gesetzt sind als erwartet? Da fallen mir ehrlich gesagt auf Anhieb keine ein. |
AW: Try Except Problem
Zitat:
Delphi-Quellcode:
:mrgreen:
{$PUSH}
{$X+} machwas; {$POP} Gruß, Sven |
AW: Try Except Problem
Zitat:
Delphi-Quellcode:
Klar, wer ist so dämlich... aber es ging ja nur ums einfallen.
if CalculateFunctionWithSideEffec1 or CalculateFunctionWithSideEffec2 then
|
AW: Try Except Problem
Zitat:
|
AW: Try Except Problem
Zitat:
Wenn die 0 als Fehler definiert ist und alle Datensätze gelesenwerden müssen, egal ob gültig oder nicht, und die Anwendung nicht dialoglastig ist, dann ist so ein Konstrukt nicht ganz falsch. Gruß K-H |
AW: Try Except Problem
Doch, ist es.
Versuch mal soeinen Code zu debuggen :freak: und außerdem sind Exceptions eher für Ausnahmen und nicht zur "normalen" Programmsteuerung gedacht. ![]() ![]() ![]() |
AW: Try Except Problem
Zitat:
Niemals eine Exception blind wegfangen, sondern eher an so vielen Stellen wie möglich sogar eine Exception werfen, wenn die übergebenen Informationen so nicht verarbeitbar sind. Nur so kann ich eine zuverlässige und robuste Anwendung erstellen mit möglichst wenigen Bugs. |
AW: Try Except Problem
Zitat:
|
AW: Try Except Problem
Und wenn man dann noch in Abstraktionsebenen denkt und Exceptions der aufgerufenen niedrigeren Abstraktionsebene abfängt, interpretiert und (abstrakter) weiterleitet, hat man einen Securitymanagement um sein Subsystem gelegt, mit dem sich schon recht komplexe und leicht zu wartende große Systeme implementieren lassen.
Mit Subsystem ist hier ist die Menge von Klassen in enger Kopplung gemeint, die sich gemeinsam um die Lösung eines Problemkomplexes kümmern. Ein Beispiel ist der Communication-Layer, der die konkreten TCP- RDBMS- oder Streamexceptions abfängt, interpretiert (u.U. sogar repariert) und ggf. als 'CommunicationException' weiterleitet. Den Aufrufer interessiert es nämlich nicht, ob das gerade ein TCP-Timeout oder ein RDBMS-Lesefehler infolge explodierter Platten ist: Die Kommunikation funktioniert nicht, und das reicht ihm. |
AW: Try Except Problem
@Dejan Vu
Du solltest den einen Satz so darstellen Zitat:
|
AW: Try Except Problem
Das hast Du ja jetzt gemacht. Doppelt hält besser. :mrgreen:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:11 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