Visitenkarteninformationen für Sametime konfigurieren

3. April 2013 Posted by Manfred Meise

Lotus Sametime bietet die Möglichkeit, im Kontakte-Fenster zusätzliche Informationen zu den Benutzern (aus deren Personendokumenten im Domino Directory) einzublenden. Hierzu können neben Telefonnummer oder Titel auch ein Bild zählen. Um z.B. Bilder der Benutzer darzustellen

Image:Visitenkarteninformationen für Sametime konfigurieren
(ja ich weiß, ich sollte einmal ein aktuelleres Bild organisieren....)

empfiehlt sich die Aufnahme eines weiteren Feldes in Personendokumenten (z.B. durch Verwendung einer geschützten Teilmaske "", damit dieses beim nächsten Serverupdate nicht wieder verloren geht.) Wir verwenden ein Richttext-Feld Namens "UserPhoto", dass Benutzer selbst mit Daten füllen können (nicht müssen).
Image:Visitenkarteninformationen für Sametime konfigurieren

Damit SameTime die entsprechenden Informationen findet und bereitstellt sind einige wenige Browser-Eingriffe in der "STConfig.nsf" erforderlich

Image:Visitenkarteninformationen für Sametime konfigurieren

Zur Darstellung, welche Visitenkarteninformationen konfiguriert sind (und ob ein Bild gefunden wurde) kann folgende URL eingesetzt werden:

http://FQDN/servlet/UserInfoServlet?operation=3&setid=1&userId=CN=Hans%20Mustermann/OU=Admin/O=MyCompany

Wenn hier z.B. ein Photo (encoded) dargestellt wird, am Client jedoch nicht, so kann man (statt lange zu warten) am Client mit rechter Maustaste auf den entsprechenden Benutzereintrag im Kontakte-Fenster ein "Personeninformationen aktualisieren" wählen. Schon klappt's !

Visitenkarteninformationen fĂĽr Sametime konfigurieren

3. April 2013 Posted by Manfred Meise

Lotus Sametime bietet die Möglichkeit, im Kontakte-Fenster zusätzliche Informationen zu den Benutzern (aus deren Personendokumenten im Domino Directory) einzublenden. Hierzu können neben Telefonnummer oder Titel auch ein Bild zählen. Um z.B. Bilder der Benutzer darzustellen

Image:Visitenkarteninformationen fĂĽr Sametime konfigurieren
(ja ich weiĂź, ich sollte einmal ein aktuelleres Bild organisieren....)

empfiehlt sich die Aufnahme eines weiteren Feldes in Personendokumenten (z.B. durch Verwendung einer geschützten Teilmaske "", damit dieses beim nächsten Serverupdate nicht wieder verloren geht.) Wir verwenden ein Richttext-Feld Namens "UserPhoto", dass Benutzer selbst mit Daten füllen können (nicht müssen).
Image:Visitenkarteninformationen fĂĽr Sametime konfigurieren

Damit SameTime die entsprechenden Informationen findet und bereitstellt sind einige wenige Browser-Eingriffe in der "STConfig.nsf" erforderlich

Image:Visitenkarteninformationen fĂĽr Sametime konfigurieren

Zur Darstellung, welche Visitenkarteninformationen konfiguriert sind (und ob ein Bild gefunden wurde) kann folgende URL eingesetzt werden:

http://FQDN/servlet/UserInfoServlet?operation=3&setid=1&userId=CN=Hans%20Mustermann/OU=Admin/O=MyCompany

Wenn hier z.B. ein Photo (encoded) dargestellt wird, am Client jedoch nicht, so kann man (statt lange zu warten) am Client mit rechter Maustaste auf den entsprechenden Benutzereintrag im Kontakte-Fenster ein "Personeninformationen aktualisieren" wählen. Schon klappt's !

Lotus Notes Clients stürzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie bisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im Grünes Bereich. Mein Lotus Notes Client repliziert wieder für mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

Lotus Notes Clients stürzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie beisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im Grünes Bereich. Mein Lotus Notes Client repliziert wieder für mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

Lotus Notes Clients stürzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie bisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im Grünes Bereich. Mein Lotus Notes Client repliziert wieder für mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

Lotus Notes Clients stĂĽrzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie bisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im GrĂĽnes Bereich. Mein Lotus Notes Client repliziert wieder fĂĽr mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

Lotus Notes Clients stĂĽrzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie bisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im GrĂĽnes Bereich. Mein Lotus Notes Client repliziert wieder fĂĽr mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

Lotus Notes Clients stürzt beim Replizieren ab

18. März 2013 Posted by Manfred Meise

Es gibt Tage (wie diesen) an dem ich meinen Lotus Notes Client hasse. Habe ich doch soeben ein Dokument in einer lokalen Datenbank bearbeitet und gespeichert. Danach wollte ich Datenbank mit meinem Server replizieren..... Crash ! Mein Lotus Notes Client stürzt ab. Dieses Verhalten lässt sich sogar reproduzieren: beim Replizieren einer beliebigen Datenbank stürzt mein Client reproduzierbar ab. Leider sind die erstellten Crash-Dumps (obwohl vorsorglich aktiviert) vollkommen nutzlos (Dateien ohne Inhalt : 0kB groß).

Ein vollständiger Windows Neustart scheint anfangs Besserung zu versprechen (der Absturz beim Replizieren ließ einen Augenblick auf sich warten). Nun schien guter Rat teuer: Knowledgebase Einträge der IBM verwiesen lediglich auf einzelne Datenbanken, bei denen dieses Verhalten auftritt.

Doch nachgedacht und als Ursache eine fehlerhafte Replikatorseite in der Arbeitsumgebung in Betracht gezogen! Deshalb habe ich eine neue Arbeitsumgebung (mit den gleichen Daten wie bisher) erstellt (keine Kopie des Dokumentes !!!!) und aktiviert. Und siehe da: Alles im Grünes Bereich. Mein Lotus Notes Client repliziert wieder für mich. Nun kann ich wieder anfangen mich meiner eigentlichen Aufgabe zu widmen.

“Object variable not set” beim Beenden eines Agenten – Die Rache mangelnder Fehlerbehandlung

18. März 2013 Posted by Manfred Meise

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.

“Object variable not set” beim Beenden eines Agenten – Die Rache mangelnder Fehlerbehandlung

18. März 2013 Posted by Manfred Meise

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, dass Fehler stufenweise bis an den oberste Aufruferebene zurückliefert). Man tut sich selbst etwas gutes.

“Object variable not set” beim Beenden eines Agenten – Die Rache mangelnder Fehlerbehandlung

18. März 2013 Posted by Manfred Meise

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.

“Object variable not set” beim Beenden eines Agenten – Die Rache mangelnder Fehlerbehandlung

18. März 2013 Posted by Manfred Meise

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.

ArrayGetIndex erzeugt zur Laufzeit “Illegal use of null”

11. März 2013 Posted by Manfred Meise

Manchmal sucht man seine eigenen LotusScript Fehler schon etwas länger... Hier so ein Beispiel, bei welchem sich ein bischen Nachdenken mit Abstand lohnt.

Das Codebeispiel (z.B. eines interaktiven Agenten):

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Dieser Code funktioniert wunderbar, sofern man als Suchbegriff z.B. die Strings 1 oder 2 oder 4 eingibt. Versucht man aber den Begriff zu suchen, der nicht in der Liste enthalten ist, produziert man:

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Hmmm.... Habe doch mit "ArrayGetIndex" sonst recht gut klar kommen können. Wer erkennt den Fehler auf Anhieb?

Klar: Falsche Typdeklaration für "index". Dieses muss ein Variant sein (damit ihm die ArrayGetIndex-Funktion auch den Wert "null" zuweisen kann), wenn der Suchbegriff nicht gefunden wird.

ArrayGetIndex erzeugt zur Laufzeit “Illegal use of null”

11. März 2013 Posted by Manfred Meise

Manchmal sucht man seine eigenen LotusScript Fehler schon etwas länger... Hier so ein Beispiel, bei welchem sich ein bischen Nachdenken mit Abstand lohnt.

Das Codebeispiel (z.B. eines interaktiven Agenten):

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Dieser Code funktioniert wunderbar, sofern man als Suchbegriff z.B. die Strings 1 oder 2 oder 4 eingibt. Versucht man aber den Begriff zu suchen, der nicht in der Liste enthalten ist, produziert man:

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Hmmm.... Habe doch mit "ArrayGetIndex" sonst recht gut klar kommen können. Wer erkennt den Fehler auf Anhieb?

Klar: Falsche Typdeklaration für "index". Dieses muss ein Variant sein (damit ihm die ArrayGetIndex-Funktion auch den Wert "null" zuweisen kann), wenn der Suchbegriff nicht gefunden wird.

ArrayGetIndex erzeugt zur Laufzeit “Illegal use of null”

11. März 2013 Posted by Manfred Meise

Manchmal sucht man seine eigenen LotusScript Fehler schon etwas länger... Hier so ein Beispiel, bei welchem sich ein bischen Nachdenken mit Abstand lohnt.

Das Codebeispiel (z.B. eines interaktiven Agenten):

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Dieser Code funktioniert wunderbar, sofern man als Suchbegriff z.B. die Strings 1 oder 2 oder 4 eingibt. Versucht man aber den Begriff zu suchen, der nicht in der Liste enthalten ist, produziert man:

Image:ArrayGetIndex erzeugt zur Laufzeit "Illegal use of null"

Hmmm.... Habe doch mit "ArrayGetIndex" sonst recht gut klar kommen können. Wer erkennt den Fehler auf Anhieb?

Klar: Falsche Typdeklaration fĂĽr "index". Dieses muss ein Variant sein (damit ihm die ArrayGetIndex-Funktion auch den Wert "null" zuweisen kann), wenn der Suchbegriff nicht gefunden wird.