Also ein Code wie dieser macht überhaupt keinen Sinn:
Delphi-Quellcode:
try
// Establish the connection.
SQLConnection1.Connected := true;
executeButton.Enabled := true;
outputMemo.Text := '
Connection established!';
except
on E: EDatabaseError
do
ShowMessage('
Exception raised with message' + E.
Message);
end;
1. Problem:
der Programmfaden läuft weiter obwohl das Öffnen der Datenbank erfolglos was.
In der Folge wird es im weiteren Verlauf zu einer weiteren
Exception kommen.
2. Problem:
das Abfangen der
Exception und das
ShowMessage
vernichtet wichtige Informationen zur Fehlersuche.
Es geht z.B. die genaue
Exception-Klasse verloren.
Die Fehlermeldung "
Exception raised with message" ist absolut Aussagelos, es steckt keine nützliche Information drin.
3. Problem:
durch das Abfangen der
Exception, geht die Möglichkeit verloren die
Exception automatisch in eine Logdatei zu schreiben.
Wie macht man es dann richtig?
1. Regel:
Exceptions nur dann abfangen, wenn man irgendwas zur Verbesserung beitragen kann.
Die Idee man könnte eine
Exception durch abfangen irgendwie "reparieren" ist sowieso in 99% aller Fälle falsch.
Was man allerdings tun kann ist dem Benutzer möglichst gute Informationen zu geben was die Ursache b etrifft und wie er das Problem beheben kann.
Delphi-Quellcode:
try
// Establish the connection.
SQLConnection1.Connected := true;
executeButton.Enabled := true;
outputMemo.Text := '
Connection established!';
except
on E:
Exception do
begin
// dem Benutzer und dem Programmierer eine aussagekräftige Meldung geben
// allgemeine Beschreibung zu Beginn der Meldung
E.
Message := '
Fehler beim Öffnen der Datenbank'#13#10+
E.
Message + #13#10 +
// Details für Programmierer am Ende der Message
SQLConnection1.ConnectionString;
// um den Benutzer optimal zu unterstützen kann man den HelpContext setzen
E.HelpContext := HELPCONTEXT_CONNECTION_FAILED;
raise;
// Exception neu auslösen, Exceptionklasse bleibt erhalten
end;
end;
2. Regel:
nicht Exceptions abfangen und irgendwas mit
ShowMessage
anzeigen.
Showessage hat in dem Code nicht verloren.
Stellt dir vor die
Exception tritt in einer Schleife mit >100 Durchläufen auf.
Ständig popt die gleiche Meldung auf; man kann das Programm nur noch abschiesen
3. Regel:
Man sollte
raise
wesentlich öfters verwenden als
try...except
.
In dem man eigene
Exception-Klassen deklariert und diese dann raised kann man besondern in großen Programmen die Fehlerursache genauer lokalisiert.
4. Regel:
Das Prinzip der Informationanreicherung schachteln
Delphi-Quellcode:
procedure TDataModule.CalcTaxInternal(IdCompany:Integer);
begin
// jede Menge komplizierter Code zur Steuerberechnung
...
end;
procedure TDataModule.CalcTax(IdCompany:Integer);
begin
try
CalcTaxInternal(IdCompany);
except
on E:
Exception do
begin
E.
Message := '
Fehler bei Steuerberechnung für Firma '+IntToStr(IdCompany)#13#10+
E.
Message:
E.HelpContext := HELPCONTEXT_TAX_CALC_ERROR;
raise;
// Exception neu auslösen, Exceptionklasse bleibt erhalten
end;
end;
Selbst bei einer Zugriffsverletzung innerhalb von CalcTaxInternal() bekommt der Benutzer und der Programmierer so eine gute Info wo das Problem ist.
Die eigentliche Steuerberechnung bleibt völlig frei von störenden
try ... except
.