Twitter

 6.5.x  7.x  8.0.x  8.5.x 

"Object variable not set" beim Beenden eines Agenten - Die Rache mangelnder Fehlerbehandlung

Manfred Meise  18 März 2013 09:46:00
 
Jüngst habe ich eine Menge Zeit für die Fehlersuche bei einem Agenten (welcher zahlreich eigene Klassen nutzt) verwendet. Dieser erzeugte (in einzelnen seltenen Fällen) einen Laufzeitfehler "Object variable not" - wer kennt ihn nicht?.... Offensichtlich eine Stelle Code, bei der schlampig programmiert wurde - doch wo? Nach intensiver Analyse stellt sich heraus, dass dieser Fehler nach dem letzten ausführbaren Statement ("Exit Sub" im Terminate Event) des Agenten generiert wurde. Schnell ist mir klar: Das kann nur ein Destructor ("Sub Delete") einer eigenen Klasse sein - doch welcher?

Das Analyseergebnis (in vereinfachter Form) zeigt den Übeltäter:

 
Option
Public
Option
Declare
%Include
"LsConst.lss"
Class
myClass
    Private m_doc As NotesDocument
    Sub New (doc As NotesDocument)
            Set Me.m_doc = doc
    End Sub
    Sub Delete
            Call Me.m_doc.Save(True, False)        
    End Sub
End
Class
Sub
Initialize
    Dim objMyClass As MyClass
    Set objMyClass = New MyClass (Nothing)
End
Sub


Hier kann es (durch verschiedene Ursachen) geschehen, dass das bei der Instanziierung übergebene NotesDocument beim Zerstören eines Objektes der Klasse nicht mehr existiert.

Hätte ich hier

1. Konservativ codiert (Prüfung ob ein vermutetes Objekt auch vorhanden ist, bevor man darauf zugreift)
und/oder
2. Fehlerbehandlung in jede Routine, sowie Methoden von Klassen

eingebaut, dann wird der Umfang des Codes bei einfachen Funktionen zwar erheblich größer, doch auch die Fehlersuche ganz einfach.

 
Option
Public
Option
Declare

%Include
"LsConst.lss"
Class
myClass
    Private m_doc As NotesDocument
    Sub New (doc As NotesDocument)
            On Error GoTo ErrorBubble        
            Set Me.m_doc = doc
SingleExit:
            Exit Sub
            '......................................................................................................        
ErrorBubble:        
            Error Err, Error & Chr(13) & { --> in } & TypeName(Me) & {.} & GetThreadInfo (LSI_THREAD_PROC) &  { : } & Erl        
            Resume SingleExit
    End Sub
    Sub Delete
            On Error GoTo ErrorBubble
            If Not (Me.m_doc Is Nothing) Then Call Me.m_doc.Save(True, False)        'Konservative Programmierung
            Call Me.m_doc.Save(True, False)                                                'Riskante Programmierung
SingleExit:
            Exit Sub
            '......................................................................................................        
ErrorBubble:        
            Error Err, Error & Chr(13) & { --> in } & TypeName(Me) & {.} & GetThreadInfo (LSI_THREAD_PROC) &  { : } & Erl        
            Resume SingleExit
    End Sub
End
Class
Sub
Initialize
    On Error GoTo ErrorBubble
    Dim objMyClass As MyClass
    Set objMyClass = New MyClass (Nothing)
SingleExit:
    Exit Sub
    '......................................................................................................        
ErrorBubble:        
    Error Err, Error & Chr(13) & { --> in } & GetThreadInfo (LSI_THREAD_PROC) &  { : } & Erl        
    Resume SingleExit
End
Sub


Image:"Object variable not set" beim Beenden eines Agenten - Die Rache mangelnder Fehlerbehandlung
Diese Fehlermeldung weist auf die Zeile 28 der Methode "Delete" in Klasse "MyClass", welche in Zeile 11 der Initialize Methode des Agenten ausgelöst wurde.

Also: Stets Fehlerbehandlungen einbauen (im Beispiel ein simples "Bubble up" Prinzip, das Fehler stufenweise bis an die oberste Aufruferebene zurückliefert). Man tut sich selbst etwas gutes.