Jetzt gebe ich auch noch mal meinen Senf dazu (obwohl ich den immer noch nicht mag...)
1. Bedeutung des Begriffs Exception
Für mich widerspricht es dem eigentlichen Sinn wenn man Exceptions dazu benutzt, einfache Fehlerbedingungen zu signalisieren. Für mich ist eine
Exception im wörtlichen Sinne eine
Ausnahmebedingung: eine Programmzustand, in dem nicht mehr mit der normalen Ausführung fortgefahren werden kann. Nicht genug Speicher, unzureichende Systemresourcen, die CD mit der EXE-Datei des Programms wurde aus dem Laufwerk genommen oder ähnliches, und sicher auch Programmierfehler wie fehlerhafte Indizes. Ganz bestimmt aber nicht so etwas wie ein einfacher Fehlerzustand. Der kann zwar stellenweise asynchron auftreten, also ohne direkten Bezug zur aktuell aufgerufenen Prozedur, aber ich denke das ist kein Grund aus einem Ereignis (-> Event) eine
Exception (-> Ausnahmebedingung) zu machen.
2. Was der "normale" Programmierer daraus macht
In meinen Augen macht ein Block wie
Delphi-Quellcode:
try
TueIrgendWas;
except
on E:
Exception do
MessageDlg(E.
Message, mtError, [mbOk], 0);
end;
überhaupt keinen Sinn - da kann ich die
Exception auch gleich bis zum obersten Level durchschlagen lassen, dort wird nämlich auch einfach eine Meldung ausgegeben. Diese Form sieht man aber am häufigsten. Noch schlimmer ist, dass die meisten Programmierer dann den Fehler machen, einfach im Code fortzufahren als ob nichts geschehen wäre, der try-except Block in diesem Fall also gerade eine Dummheit ist.
3. Was ich daraus mache
Persönlich benutze ich
Exception-Handling fast ausschließlich für try-finally Blöcke zum Ressourcenschutz. Nur an bestimmten Stellen verwende ich try-except und zwar dort, wo ich mit einem möglichen Fehlschlagen rechne. Z.B. wenn ich ein TFileStream ohne vorherige Abfrage mit FileExists öffne, was ja sowieso wenig Sinn macht, denn es kann ja sein dass es die Datei gibt aber ich sie trotzdem nicht öffnen darf.
4. Der Nutzen
Praktisch finde ich durchaus, dass SEH den Sourcecode übersichtlicher macht. Ich finde z.B. die erste Variante wesentlich besser zu lesen als die zweite:
Delphi-Quellcode:
procedure Variante1;
begin
TueDies;
TueDas;
if StimmtDas
then
TueIrgendWas
else
TueWasAnderes;
// Kein Rückgabewert notwendig, Exception
// schlägt durch in die aufrufende Routine
end;
function Variante2: boolean;
begin
if TueDies <> 0
then
Result = false
//<-- 1 signalisiert Fehler
else if TueDas
in [0, 7, 24]
then
Result = false
//<-- 0 = nicht gefunden, 7 = zu groß, 24 = zu alt
else
case StimmtDas
of
5, 13: Result = false;
//<-- Fehlercodes
1: Result := TueIrgendWas = 1;
0: Result := TueWasAnderes = 0;
end;
end;
Ich kann mich noch gut an die ersten Code-Beispiele von Microsoft zur Windows-
API /
GDI-Programmierung erinnern, wo hinter jedem Prozeduraufruf (GetDC, CreateBrush, SelectObject, DeleteObject, ReleaseDC) immer wieder der ganze Salmon hing, also jedesmal eine separate Fehlerbehandlung mit abschließendem return. Ich denke da ist SEH die bessere Alternative.
<Vorbehalt="Muss ich noch mal genau drüber nachdenken">
5. Exceptions zur Fehlerbehandlung
Um eine
Exception für die normale Fehlerbehandlung zu "missbrauchen" fehlt ein ganz wichtiges Feature, nämlich das Fortfahren an der Fehlerstelle. Im Grunde so etwas wie das "Resume Next" in Visual Basic. Dann könnte man nämlich in Fällen wie beim "EConnectionClosedGracefully" den Fehler dankend zu Kenntnis nehmen und an der alten Stelle fortfahren.
</Vorbehalt>
Hinweis: Nachträglich noch etwas editiert, um es strukturierter aussehen zu lassen