Best Practices > Diskussionen zu Best Practices
Best Practices: Error Handling in Lotus Script: Einleitung
Semeaphoros:
An verschiedenen Stellen haben wir unterdessen über das Error-Handling geschrieben und verschiedentlich versprochen, dass wir das zum selbständigen Thema erheben wollen. Ich möchte damit hier jetzt anfangen. Folgendes Vorgehen habe ich mir vorgestellt (wobei die Diskussion diesen Weg bestimmt erweitern wird):
Ich werde im nächsten Posting mal zuerst einen generellen Ueberblick über Runtime-Errors in LotusScript machen, in den dann folgenden Postings stelle ich dann die für das Error-Handling relevanten LotusScript Statements vorstellen. Daraufhin möchte ich die Diskussion in der Form eröffnen, dass einzelne von Euch ihre eigenen Taktiken für das Error-Handling vorstellen. Bernhard hat kürzlich schon mal ein ganz grobes Grundgerüst skizziert, wie man das angehen kann. Gleichzeitig werden dabei auch die Haken und Ecken des Error-Handlings auftauchen, und es wird hoffentlich an manchen Orten zum Ueberdenken des Error-Handling-Ansatzes führen, tatsächlich ist es eines der Gebiete, die mehr als verträglich vernachlässigt wird.
Also, gleich gehts los ...... :D
PS: Ich will auch endlich meinen eigenen Thread haben .... ;D
Semeaphoros:
Eigentlich gibt es in einer LS-Applikation 3 Sorten von Fehlern, die während der Laufzeit auftreten können:
1. Fehler, welche von LotusScript entdeckt und mit einer Fehlermeldung versehen werden. Wenn man gegen solche Fehler nichts unternimmt, bekommt der Benutzer eine Fehlermeldung und das Script bricht ab. Beispiel:
--- Code: ---Resultat = Var1 / 0
--- Ende Code ---
erzeugt einen Fehler, weil die Division durch 0 nicht erlaubt ist.
2. Fehlerzustände, die LotusScript nicht eindeutig als solche erkennen kann, auf die das Programm dann entweder selber reagieren muss, oder es führt dann später im Code zu einer entsprechenden Fehlfunktion des Programmes, weil die Umstände nicht so waren wie erwartet. Beispiel:
--- Code: ---Dim db As NotesDatabase
Call db.Open( "HongKong", "sales.nsf"
--- Ende Code ---
Wenn auf dem Server "HonKong" die Datenbank "sales.nsf" nicht existiert, passiert hier mal gar nichts. Erst wenn ich zum Beispiel mit db.GetDociumentById(..), erhalte ich die Fehlermeldung, dass die Datenbank nicht offen ist.
3. Dann gibt es natürlich auch noch die logischen Fehler. Das Programm läuft zwar korrekt ab, erzeugt weder Fehlermeldungen noch werden "illegale Zustände" wie unter 2. erzeugt, aber trotzdem ist das Ergebnis nicht das, was man erwartet. Entweder stimmt die Applikationslogik nicht, oder das Programm ist nicht nach den Spezifikationen umgesetzt worden. Natürlich können wir hier nicht über diese Probleme reden, da diese ganz individuell angegangen werden können. Was wir hier diskutieren können, sind Taktiken, die man anwenden kann, um diese Probleme einzugrenzen und zu lösen.
Semeaphoros:
Die oben aufgeführten einzelnen Fehlerkategorien erfordern natürlich unterschiedliche Ansätze, um sie zu "behandeln":
1. Von LotusScript erkannte und behandelte Fehler
Da in diesem Fall ein Abbruch des Programmes erfolgt, ist dies eigenlich für den Anwender eine Katastrophensituation, die man wenn immer möglich vermeiden sollte. LotusScript stellt dafür eine ganze Reihe von Statements zur Verfügung, die einem ermöglichen, die "Situation" zu retten. Im Vordergrund stett das On Error Statement. Diese Fehlerbehandlungs-Mechanismen werden in den nächsten Postings im einzelnen noch vorgestellt.
2. Fehlersituationen, die von LotusScript nicht mit einem "Fehler belohnt" werden
Hier gibt es verschiedene Strategien:
A Gar nichts machen und warten, bis irgendwann einmal später die Situation 1. eintrifft und ein Fehler generiert wird, der abgehandelt werden kann.
B In Abhängigkeit von der Situation versuchen, festzustellen, ob das Statement den gewünschten Erfolg gebracht hat. Im Fall von NotesDatabase.Open gibt es da verschiedene Varianten:
Diese Methode hat einen Rückgabewert: True, wenn die Datenbank geöffnet werden konnte, andernfalls False, wir können also den Rückgabewert auswerten:
--- Code: ---Dim db As NotesDatabase
If Not db.Open( "HongKong", "sales.nsf" Then
Messagebox "Die Datenbank konnte nicht geöffnet werden"
Else
........
End If
--- Ende Code ---
Alternativ kann die Eigenschaft IsOpen abgefragt werden:
--- Code: ---Dim db As NotesDatabase
Call db.Open( "HongKong", "sales.nsf"
If Not db.IsOpen Then
Messagebox "Die Datenbank konnte nicht geöffnet werden"
Else
........
End If
--- Ende Code ---
Die Designer-Hilfe ist dabei zu Rate zu ziehen, bei jedem Befehl, bei jeder Methode und Funktion ist jeweils angegeben, was passiert, wenn nicht das erwartete Resultat erreicht wird. Insbesondere ist zu beachten, dass es grundsätzlich keine Systematik vorhanden ist, wann Methode 1 mit der Fehlermeldung und wann Methode 2 über einen Status-Returnwert oder eine Status-Abfrage oder ähnliches zur Anwendung gelangen muss.
Semeaphoros:
Das On Error Statement verändert das Verhalten von LotusScript. Sobald dieses Statement ausgeführt wurde, wird keine Fehlermeldung generiert, sondern eine vom Programmierer definierte Aktion ausgeführt.
1. On Error ohne Fehlernummer
Diese Variante von On Error kann in 3 verschiedenen Formen erscheinen:
a. On Error Goto Sprungadresse
In diesem Falle wird der Code ausgeführt, der hinter der Sprungadresse (Label) aufgeführt wird. Dieser Code muss mit einer Form von Resume abgeschlossen werden, damit LotusScript weiss, dass der Fehler jetzt behandelt ist. (Das besagt nciht zwingend, dass der Fehler dadurch behoben oder beseitigt wurde!).
Beispiel:
--- Code: ---Sub Demo
On Error Goto ErrHandler
...... hier steht der Programmcode, bei einem Fehler wird statt einer Fehlermeldung
der unten aufgeführte Code ausgeführt
.....
Exit Sub
ErrHandler:
Print "Es ist ein Fehler aufgetreten" ' Hey, hier sollte sinnvoller Code stehen :-)
Resume
--- Ende Code ---
b. On Error Goto 0
Mit diesem Statement wird eine besondere Fehlerbehandlungsroutine wieder zurückgesetzt. Es hängt jetzt davon ab, ob meherere On Error-Statements definiert waren oder nicht. Dieses Statement setzt zurück auf den Zustand, der vor dem zuletzt ausgeführten On Error Statement existierte. Allenfalls wird dadurch wieder das LotusScript Standardverfahren hergestellt. Auch wenn On Error Goto 0 nicht verwendet wird, werden alle On Error-Statements deaktiviert, sobald man an das Ende eines Moduls (sub oder function oder Methode) erreicht hat und das Modul verlässt. Beispiel unter c.
c. On Error Resume Next
Eine der gefährlichsten Konstruktionen überhaupt, die Fehlermeldung wird ganz einfach unterdrückt und das Programm mit dem nächsten Statement fortgesetzt. Auf diesem Weg werden Fehler vom Typ 1. zu Fehlern vom Typ 2., die anschliessend eine Ueberprüfung des Zustandes erfordern.
--- Code: ---Dim dir As NotesDbDirectory
Dim db As NotesDatabase
Set dir = s.GetDbDirectory("")
On Error Resume Next
Set db = dir.CreateDatabase("quack.nsf", True)
On Error Goto 0
If db is nothing then
Messagebox "Datenbank existiert bereits"
End if
--- Ende Code ---
2. On Error mit Fehlernummer
Alle drei oben beschriebenen Varianten können mit einer Fehlernummer versehen werden. Während bei obigen Beispielen immer alle Fehlermeldungen unterdrückt und speziell behandelt werden, lässt sich mit Angabe einer Fehlernummer dieses Verfahren auf genau eine einzige Fehlermeldung beschränken. Beispiel:
--- Code: ---Sub Demo
On Error 11 goto DivByZero
Resultat = Var1 / 0
On Error Goto 0
Exit Sub
DivByZero:
Messagebox "Division durch 0 aufgetreten"
Resume Next
End Sub
--- Ende Code ---
Die Fehlernummern findet man in der Designerhilfe. Ausserdem kann man statt mit Nummern mit "sprechenden" Konstanten arbeiten, wenn man die folgenden Dateien mit HIlfe von %include in sein Programm integriert:
lsxbeerr.lss defines constants for errors raised by Domino Designer back-end methods.
lsxuierr.lss defines constants for errors raised by Domino Designer front-end (UI) methods.
lserr.lss defines constants for errors raised by LotusScript.
lsconst.lss defines constants for use as arguments in LotusScript statements and functions.
Semeaphoros:
Resume schliesst eine Fehlerbehandlungsroutine ab und teilt somit LotusScript mit, dass der Fehler nicht mehr als solcher zu betrachten ist (technisch gemeint natürlich)
Das Statement kann in 4 Formen auftreten:
Resume
Resume 0
Resume Next
Resume Sprungadresse
Resume und Resume 0 sind gleichbedeutend:
Mit diesen Befehlen wird das Statement, das den Fehler verurstachte, noch einmal ausgeführt: Achtung: das darf natürlich nur gemacht werden, wenn in der Fehlerbehandlungsroutine der Grund für den Fehler beseitigt wurde, also beispielsweise nach einem neuen Dateinamen gefragt wurde. Sonst passiert der Fehler ja gleich noch einmal und wir landen gleich wieder am selben Ort ....... und haben eine Endlosschleife ...... (Hinweis für TMC: Das wäre vielleicht als Beispiel in die Weihnachsschleifen-Sammlung aufzunehmen)
Mit Resume Next wird die Programmausführung beim nächsten Befehl hinter dem Statement, welches den Fehler auslöste, fortgesetzt. Auch hier gilt: im Fehlerbehandlungsprgramm sollte dafür gesorgt werden, dass das Programm weitergeführt werden kann. Hier ist es allerdings nicht so tragisch wie oben, das Programm wird ja einen Schritt nach der Fehlerstelle weitergeführt. Also auch wenn ein weiterer Fehler auftritt und die Routine wieder aufgerufen wird, kommen wir trotzdem im Programmablauf vorwärts. Vorsicht ist natürlich angebracht.
Resume Sprungadresse
Hier können wir das Programm an einem beliebigen Label fortsetzen, damit Teile, die sonst durch den Fehler nicht laufen würden, überspringen.
Beispiel:
--- Code: ---Sub Demo
On Error Goto ErrHandler
... hier der Code
AfterError:
Print "Routine Demo beendet"
Exit Sub
ErrHandler:
Print "Es ist ein Fehler aufgetreten"
Resume AfterError:
End Sub
--- Ende Code ---
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln