Manage Learn to apply best practices and optimize your operations.

Automatic error notification

This tip describes a procedure for automatic error notification.

This tip is designed to give a developer immediate feedback from users whenever an error occurs. If defined in a script library it can be initialised as a global object and called from any error routine. This class will email the developer/support group with specific details of any error using just 1 line of code. This allows the developer to not only be pro-active but also have a more detailed understanding of what is happening out in user land with his or her code.

With the following two lines of code not only is the user advised of the error but also an email containing links and specific details has automatically been sent to the developer.

Call cdWatch.notifyUser
("IT Support has been notified")
Call cdWatch.notifyDev(db, doc)

Prior to using the code ensure you replace {Enter a valid email address or group} with an appropriate address. The remarks section at the top of the code gives full details of the syntax.


Public Class codeWatcher
%REM
**************** Properties**********
****** 

userName          -   Returns user 
common name, read only
scriptName        -   Set as 
parameter in New method, read/write, 
cannot be null
devEmail           -   Hard coded default, 
read/write, cannot be null
comment           -   Initial value null, 
read/write

**************** Methods ********
******** 

notifyUser         -  Displays a standard 
error messagebox. 
                         Syntax:
call codeWatcher.notifyUser(Comment$)

                          Parameters:
                                    Comment$ - 
String, whatever message in addition to 
the default "Error" & Str(Err) & ": " & 
Error$ message

notifyDev          - Sends a standard email 
message to the developer group/individual 
defined by the devEmail property
                         Syntax:
                                    call codeWatcher.
notifyDev(notesdatabase, notesdocument) 
As Integer
                                                                                    
  or
                                    call codeWatcher.
notifyDev(notesdatabase, "") As Integer

                          Parameters:               
                                    notesdatabase - 
Notesdatabase object for the current database
                                    notesdocument - 
Notesdocument object for current document
 being processed or a null string ("") 
if not handling documents

************************************************


CodeWatcher is designed as a simple 
means of notifying the developer if a run-time
 error occures.

To instantiate the object do the following
Dim cWatcher As New codeWatcher(Lsi_info(2)) 
where "TextCodeWatcher" is the module name
 and db is the database object

set the scriptName property to decribe the 
routine/action/button/agent where the error occures
 either at the top of the code or during the 
error handling routine
errorProject.scriptName = "Form - 
User Details (" + Lsi_info(2) + ")"

Call the notifyDev function from the error 
handling routine 
i.e.: Call cWatcher.notifyDev(db,doc)

If you are not working with documents 
pass a null string 
i.e.: Call cWatcher.notifyDev(db,"")

*************************** Setting the 
scriptName property
The scriptName property tells the
 developer where the error occured, i.e. in the query save 
event or in a particular Action. This value is 
set by the developer either at the top of the event or just
prior to calling the notifyDev function in the error handling routine.

The Lsi_info(12) function will return the name 
of the sub/function or module where the error 
occured. Lsi_info() cannot always be used in 
place of scriptName as the module name for an action 
for example would simply be "click" which 
isn't particularly instructive.  For example if an 
error occured in a hypothetical action called 
"Get user details" while running the 
"lookupInNAB" function 
the error email would include the following: 

Process: "Action - Get user details" (Note: 
As scriptName is set by the programmer 
this value is always going to be subjective)
Sub/Function/Module: "lookupInNAB"

If the error occured in the "Click" event of the
 "Get user details" action then
 Sub/Function/Module: "Click" would be returned.

Another issue is that the Form name can 
only be returned after a document has been
 initally saved, it may therefore be prudent to 
set scriptName to include the form. i.e.
errorProject.scriptName = "Form - User Details
 (" + Lsi_info(12) + ")"  will set the scriptName 
property to "Form - User Details (Query Save)" 
if called from the Query Save
event or errorProject.scriptName = "Form - User Details, Action - (Get user details)". NOTE: If a document is not passed to the notifyDev routine then the function will skip that section of code. Once the codeWatcher object has been set mark the position in the code by setting the "comment" property. i.e.: cWatcher.comment = "whatever comment you want to mark position in code" If codeWatcher is called as global the scriptName property can be reset as required. This code was designed with a hard-coded developer email however inserting a lookup routine to set the devEmail property in new is a possibility or it can be changed wherever appropriate in the code %END REM Private m_userName As String Private m_devEmail As String Private m_scriptName As String Private m_comment As String Sub new(currentScript As String) Dim session As New NotesSession m_userName = session.commonUserName m_scriptName = currentScript m_devEmail ={Enter a valid email address or group} m_comment="" End Sub Property Get userName As String userName= m_userName End Property Property Get scriptName As String scriptName=m_scriptName End Property Property Set scriptName As String If Not scriptName = "" Then 'don't allow a blank scriptName, if "" keep current value m_scriptName = scriptName End If End Property Property Get devEmail As String devEmail=m_devEmail End Property Property Set devEmail As String If Not devEmail = "" Then 'don't allow a blank devEmail, if "" keep current value m_devEmail = devEmail End If End Property Property Get comment As String comment=m_comment End Property Property Set comment As String m_comment=comment End Property Sub notifyUser(Comment As String) %REM This method will notify the user an issue has occurred. If a comment is passed it will be added to bottom of the messagebox %END REM If Len(Comment) > 0 Then Comment = Chr(13) + Comment End If Messagebox "Error" & Str(Err) & ": " & Error$ + Comment,48,"Error" & Str(Err) End Sub Function notifyDev(db As notesdatabase, doc As Variant) As Integer %REM This method will send an email to the address in the m_devEmail property, the scriptName property will give the developer some idea of where the error occured. %END REM Dim memodoc As notesdocument Dim session As NotesSession Dim memodoc_Body As notesrichtextitem Dim cLoc As String Set session = db.Parent Set memodoc = db.CreateDocument memodoc.form = "Memo" memodoc.SendTo = m_devEmail memodoc.Subject = {Error Notification: - At } + Format(Now,"Medium Time") + { on } + Format(Now,"Medium Date") + { } + Me.userName + { encountered a "} & Str(Err) & ": " & Error$ & {" Error in the } + Me.scriptName + { Process.} Set memodoc_Body = memodoc. CreateRichTextItem( "body" ) Call memodoc_Body.AppendText( {At } + Format(Now,"Medium Time") + { on } + Format(Now,"Medium Date") + { } + Me.userName + { encountered a "} & Str(Err) & ": " & Error$ & {" Error in the } + Me.scriptName + { Process.}) Call memodoc_Body.AddNewLine( 2) Call memodoc_Body.AppendText( {User: } + Me.username) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Error Date: } + Format(Now,"Medium Date") ) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Error Time: } + Format(Now,"Medium Time") ) Call memodoc_Body.AddNewLine( 2) Call memodoc_Body.AppendText ( {Database: } + db.Title) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Server Path: } + db.filePath) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Server Name: } + db.server) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Client Version: } + Session.NotesVersion) Call memodoc_Body.AddNewLine( 2) If Isobject(doc) Then If Not doc Is Nothing Then If doc.isnewnote Then Call memodoc_Body.AppendText ( {Formname: New document, please manually check with user.}) Else Call memodoc_Body.AppendText ( {Formname: } + doc.form(0)) End If Call memodoc_Body.AddNewLine( 1) End If End If Call memodoc_Body.AppendText ( {Error: } + Str(Err) & ": " & Error$) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Process: } + Me.scriptName ) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Sub/Function/Module: } + Lsi_info(12) ) Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Line No: } + Cstr(Erl()) + cLoc) If Not m_comment="" Then Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Developer Comment: } + Me.comment) End If Call memodoc_Body.AddNewLine( 2) Call memodoc_Body.AppendText ( {Link to database: }) Call memodoc_Body.AppendDocLink ( db, {Database where error occurred} ) If Isobject(doc) Then If Not doc Is Nothing Then Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {Link to document: }) Call memodoc_Body.AppendDocLink ( doc, {Document where error occurred} ) If doc.isnewnote Then Call memodoc_Body.AddNewLine( 1) Call memodoc_Body.AppendText ( {(Note: Error occurred prior to initial save therefore doclink may be invalid.) } ) End If End If End If Call memodoc.send(False) notifyDev = True End Function End Class

Dig Deeper on LotusScript

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.

-ADS BY GOOGLE

SearchWindowsServer

Search400

  • iSeries tutorials

    Search400.com's tutorials provide in-depth information on the iSeries. Our iSeries tutorials address areas you need to know about...

  • V6R1 upgrade planning checklist

    When upgrading to V6R1, make sure your software will be supported, your programs will function and the correct PTFs have been ...

  • Connecting multiple iSeries systems through DDM

    Working with databases over multiple iSeries systems can be simple when remotely connecting logical partitions with distributed ...

SearchDataCenter

SearchContentManagement

Close