Einzelnen Beitrag anzeigen

Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#10

AW: Dokumentation und Exceptions - Wann muss ich was erwarten?

  Alt 6. Jun 2013, 12:20
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 .
fork me on Github

Geändert von sx2008 ( 6. Jun 2013 um 12:22 Uhr)
  Mit Zitat antworten Zitat