Der Epina Delphi-Kurs bietet Ihnen eine allgemeine Einführung in das Programmieren mit Delphi/Pascal. Mit vielen ausgearbeiteten Beispielen können Sie direkt in die Delphi-Programmierung einsteigen. Mehr dazu finden Sie hier....

Exceptions

Bei Programmen können während der Ausführung eine Vielzahl von Fehlern auftreten, die von simplen arithmetischen Problemen (z.B. eine Division durch 0), über unbefugte Zugriffe auf "fremde" Speicherbereichen, bis zu Problemen mit Files reichen können. Dabei machen nicht regelmäßig auftretende Fehler die meisten Probleme (die kann man ja beheben), sondern Fehler die nur gelegentlich oder selten auftreten und von der Vorgeschichte des Programms abhängen. Für solche Fälle muss man Code vorsehen, der nur dann ausgeführt wird, wenn ein Fehler auftritt; oder umgekehrt, der auf jeden Fall ausgeführt wird auch wenn vorher ein Fehler aufgetreten ist.

Diese beiden Fälle werden von Delphi sehr elegant mit den Konstruktionen try..except..end; und try..finally..end; abgedeckt.

Exceptions

Um Fehler abzufangen, könnte man im Prinzip jede Routine so schreiben, dass man jeweils einen Statuscode zurückgibt und den vom aufrufenden Programmteil entsprechend interpretieren lässt. Allerdings kann das sehr schnell zu einem aufgeblähten Code führen, da jeweils alle möglichen Fälle überprüft werden müssen und das auch für darunter liegende Schichten von Code gilt.

Wesentlich einfacher kann man das durch eine zentraliserte Handhabung von Fehlerzuständen lösen - dazu dienen die sogenannten "Exceptions" (Ausnahmezustände), die bei Fehlerzuständen ausgelöst werden und dem Programmierer die Möglichkeit geben, korrigierend einzugreifen (und eine damit eine Fehlermeldung zu vermeiden). Reagiert man auf auftretente Exceptions nicht, so läuft das Programm in den Windows-eigenen Fehlerbehandlungsmechanismus, der meist in einem Abbruch des Programms (mit entsprechend nichtssagender Fehlermeldung) endet.

Hinweis: Man kann Exceptions auch bewusst herbeiführen, in dem man den Befehl Raise einsetzt. Dies macht vor allem dann Sinn, wenn man allgemein verwendbare Code-Bausteine programmiert und dem Nutzer dieses Bausteins eine Chance geben möchte, auftretende Fehler abzufangen.

 

try..except..end

Die Anwendung von except ist ganz einfach: Man setzt potentiell risikoreichen Code zwischen try und except, und schreibt zwischen except und end die entsprechende Fehlerbehandlungsroutine:

try
  // hier steht der Risiko-Code
except
  // hier die Fehlerbehandlungsroutine
end;

Die Fehlerbehandlungsroutine wird immer dann aufgerufen, wenn ein Fehler im try..except Teil auftritt. Das gilt auch für Unterprogramme die in diesem Teil aufgerufen werden und keine eigene Fehlerbehandlungsroutine besitzen.

Um nun auf verschiedene Fehlerarten auch verschieden reagieren zu können, kann man im except-Teil die Schlüsselwörter on und else einsetzen:


try
  // irgendwas
except
  on EIntOverflow do HandleOverflow;
  on EMathError do HandleGeneralMethError;
  else HandleUnknownError;
end;

Beispiel: Das folgende Programmbeispiel zeigt die Auswirkung eines Fehlers (Division durch 0) einmal mit Exception-Behandlung und einmal ohne. Der kritische Code dazu sieht folgendermaßen aus:

if CBoxExcept.Checked
  then begin
       try
         LblWarning.Caption := '';
         NLabResult.Value := NIOZaehler.Value/NIONenner.Value;
       except
         LblWarning.Caption := 'Der Nenner darf nicht null sein!';
       end;
       end
  else begin
       NLabResult.Value := NIOZaehler.Value/NIONenner.Value;
       end;

Ist die CheckBox angekreuzt, so wird die Exception bei Division durch 0 abgefangen, sonst nicht. Zum Download des gesamten Testprogramms klicken Sie bitte hier: prog_013.zip [227 kB]. Compilieren Sie das Programm und lassen Sie es außerhalb von Delphi laufen, sonst fängt Delphi die Exception ab.

 

try..finally..end

Tritt in einem Codeabschnitt ein Fehler auf, so bricht die Abarbeitung des Codes unmittelbar an der fehlerhaften Stelle ab. Dasselbe gilt bei der Durchführung eines Exit-Befehls. Das kann dazu führen, dass eventuell notwendiger Code (z.B. zum "Aufräumen" des Speichers) nicht mehr ausgeführt wird. Für diesen fall setzt man die try..finally..end-Konstruktion ein. Die Syntax entspricht exakt der von except:

try
  // beliebiger Code
finally
  // Code der unbedingt ausgeführt werden muss
end;

Beispiel: Eine typische Anwendung von try..finally ist die Freigabe von Instanzen, die ohne explizite Zuweisung zu einer Variablen erzeugt wurden (wie man es oft mit Dialogen macht). Im folgenden Code wird ein Open-Dialog erzeugt. Sollte aus irgendwelchen Gründen die Ausführung im try-Block abgebrochen werden, so muss auf jeden Fall der für den Open-Dialog reservierte Speicher frei gegeben werden:

with TOpenDialog.Create do
try
  if Execute then
    begin
      ... // hier wird das gewählte File geöffnet
    end;
finally
  Free; // den Open-Dialog wieder frei geben
end;

Last Update: 2008-09-09