Autor Beitrag
O'rallY
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 563



BeitragVerfasst: So 01.09.02 13:58 
Fehlerbehandlung:

Wozu ist sie da?

In jedem Programm treten Situationen auf, in denen zur Laufzeit, eine Exception (ein Fehler), auftreten kann. Ein Beispiel dafür ist eine Datei zu öffnen, die nicht existiert oder eine einfache Division durch 0. Um zu vermeiden, dass dadurch das Programm oder sogar das Betriebssystem abstürtzt, kann man, die Stellen im Programm, an denen eine Exception auftreten könnte, in einen try ... except-Block schreiben (oder in einen try ... finally-Block, obwohl dieser nicht zur Vermeidung von Exceptions dient).

Beispiel:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
try
   Memo1.Lines.LoadFromFile(AFileName);
except
   on EFOpenError do
      HandleFileOpenError; { eine selbstdefinierte Prozedur, die aufgerufen wird, wenn ein EFOpenError (FileOpenError) auftritt}

   on EOverFlow do  { es kann auch mehrmals die Klausel on ... do benutzt werden}
      HandleOverFlow;

   else
   // Fehlerbehandlung für andere Exceptions

end;


Die Anweisung (es können auch mehrere sein), die hinter try steht wird ausgeführt. Tritt dabei ein Fehler auf, springt das Programm direkt in die Exception-Routine (hinter dem Schlüsselwort except), ohne dass der weitere Programmtext im try-Block abgearbeitet wird. Handelt es sich um eine Exception vom Typ EFOpenError wird die Prozedur HandleFileOpenError ausgeführt. Diese könnte z.B. so lauten:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.HandleFileOpenError();
begin;
   ShowMessage('Datei kann nicht geöffnet werden.');
end;


Ist die Exception nicht vom Typ EFOpenError wird die Anweisung hinter dem Schlüsselwort else ausgeführt.

Wie kann ich eine eigene Exception auslösen?

Um eine eigene Exception auszulösen, muss man natürlich erstmal eine definieren. Eine Exception in Delphi ist nichts anderes als ein Klasse vom Typ Exception (nicht TException). Eine eigene Exception ist also einfach eine Ableitung der Grundklasse aller Exceptions (es hat sich eingebürgert, dass die Namen aller abgeleiteten Exceptions mit einem E beginnen):

ausblenden Delphi-Quelltext
1:
2:
type
   EMyException = class(Exception);


Um dann die Exception auszulösen, benutzt man das Schlüsselwort raise:

ausblenden Delphi-Quelltext
1:
2:
if YourPassword <> RightPassword then
   raise EMyException.Create('Falsches Passwort'); // Meldungsstring der Exception


Es ist nicht sinnvoll, die eigene Exception in einen try ... except-Block einzubauen, da man ja die Exception auslösen und nicht deren Auslösung verhindern will.

Wie kann ich Exceptions Global abfangen?

Um alle auftretenden Exceptions abzufangen, um z.B. eine eigene Fehlerbehandlungsroutine zu schreiben, kann man dem Application.OnException-Event eine Prozedur zuweisen, die bei jeder auftretenden Exception ausgeführt wird (bis auf die, die man vorher abfängt).

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.OnError(Sender: TObject; E: Exception);
begin
   ShowMessage(E.Message); // E.Message enthält den Meldungsstring der Exception
end;

procedure TForm1.FormCreate(Sender: Tobject);
begin
   Application.OnException := OnError;
end;


Wie kann ich verhindern, das eine Fehlermeldung erscheint?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
try
   ...
except
   Abort;
end;


Wie kann ich eine Exception erneut auslösen?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
try
   Memo1.Lines.LoadFromFile(AFileName);
except
   on EFOpenError do
      HandleFileOpenError;
   Raise// Befehl, um Exception nochmal auszuführen

end;


Der try ... finally-Block:

Der finally-Block enthält Anweisungen, die auf jeden Fall ausgeführt werden (auch bei Auftreten einer Exception). Sie werden auch ausgeführt, sollte innerhalb des try-Blockes die Standardprozeduren exit oder break aufgerufen werden.


Zur Grundlage dieses FAQs diente mir das Buch Nitty Gritty Delphi 6 von Frank Eller.


O'rallY