Please comment on my Error Trapping so I can improve it (1 Viewer)

Jibbadiah

James
Local time
Tomorrow, 07:27
Joined
May 19, 2005
Messages
282
Howdy folks,

I have been trying to glean little ideas from different folk to come up with robust error trapping. I have put together something below that I quite like, but I was hoping to get some feedback to see if there is anything else that I can do. Code and explanation as follows:

Firstly I input an entry in the registry so that the database will recognise that I am using it and allow me to check errors in debug mode.

Code:
SaveSetting "RBSProspects", "Admin", "DebugMode", "On"

Every module that I create has 2 variables, the first sMODULE_NAME is used to identify the module and the second, sPROC_NAME is used to identify the sub or function within the module.

e.g.
Code:
Private Const sMODULE_NAME As String = "ModDownloadFile"
Const sPROC_NAME  As String = "DownLoadStatus"

Then I use A module format that was nicely proposed by another user in this forum... really sorry that I can't give you credit... your thread has disappeared since the website was hacked.

Code:
Option Compare Database
Option Explicit
Private Const sMODULE_NAME As String = "ModEmailReportDets"
--------------------------------------------------------------------------------------------------------
Public Function MailProspectRpt()

PROC_DECLARATIONS:
    Const sPROC_NAME  As String = "MailProspectRpt"

PROC_START:
   On Error GoTo PROC_ERROR
   
PROC_MAIN:
    'Code which sends automated winzipped password-protected reports through Outlook

PROC_EXIT:
    ' Perform cleanup code here, set recordsets to nothing, etc.
    On Error Resume Next
    Exit Function

PROC_ERROR:
    If Err = -2147467259 Then
        MsgBox "You have exceeded the storage limit on your mail box. Please delete some items before clicking OK", vbOKOnly
        Resume
    End If
    
    If Err = 2501 Then
        MsgBox "You have attempted to cancel the output of the emails." & vbCrLf & _
            "This will cause major problems." & vbCrLf & _
            "Please be Patient"
        Resume
    End If
    
    Select Case iErrorHandler(Err.Description, Err.Number, sPROC_NAME, sMODULE_NAME)
    Case iERROR_DEBUG 'Breaks in Debug mode for admin (done through registry settings)
        Stop
        Resume
    Case iERROR_RETRY
        Resume
    Case iERROR_IGNORE
        Resume Next
    Case iERROR_ABORT
        Call CloseApplication
    Case Else
        ' Add "last-ditch" error handler.
        MsgBox "Error: " & Err.Description
    End Select
    Resume PROC_EXIT
   
End Function

The code above firstly checks for the instance of full mail box in outlook, or if the user cancels an action when outputting a report... I am interested to know if I can do this in a better way. I would just add additional if statements if I encounter more errors. Is this the best way to approach it?! Should I be using case statements or another technique?!

If the if statements are false it will call an Error handling module and pass it values relating to module, function/sub, error number and error description. These parameters are output in a generic message which tells the user exactly where the problem has occured, and gives the user 3 options... ignore, retry or cancel.
  • Ignore - continues to step through code using the resume keywork.
  • Retry - attempts the action again (this works well if external actions haven't finished)
  • Cancel - exits the db without saving.

There is a modGeneral module which stores the values for the Error Handler:

Code:
Private Const sMODULE_NAME As String = "ModGeneral"
Public Const iERROR_DEBUG As Integer = 1
Public Const iERROR_IGNORE As Integer = 5
Public Const iERROR_RETRY As Integer = 4
Public Const iERROR_ABORT As Integer = 3

Then the Error-Handling code is as follows.

Code:
Public Function iErrorHandler(ByVal sErr As String, ByVal iErrNo As Double, ByVal sPROC_NAME As String, ByVal sMODULE_NAME As String) As Integer
       
    Dim iRtn As Integer
    On Error GoTo Err_Trap
    
    If GetSetting("NWProspects", "Admin", "DebugMode") = "On" Then
        iRtn = 1
        MsgBox "Error" & VBA.Space$(1) & iErrNo & VBA.Space$(1) & "'" & sErr & "'" & vbCrLf & "Occured in Procedure" & VBA.Space$(1) & sPROC_NAME & VBA.Space$(1) & "in Module" & VBA.Space$(1) & sMODULE_NAME & vbCrLf, vbOKOnly, "Error in Application"
    Else:
        Screen.MousePointer = 0
        iRtn = MsgBox("Error" & VBA.Space$(1) & iErrNo & VBA.Space$(1) & "'" & sErr & "'" & vbCrLf & "Occured in Procedure" & VBA.Space$(1) & sPROC_NAME & VBA.Space$(1) & "in Module" & VBA.Space$(1) _
                        & sMODULE_NAME & vbCrLf, _
                         vbAbortRetryIgnore + vbCritical + vbDefaultButton2, _
                        "Error in Application")
    End If
    
Err_Exit:
   iErrorHandler = iRtn
   Exit Function
    
Err_Trap:
    On Error Resume Next
    MsgBox "Error" & VBA.Space$(1) & CStr(VBA.Err) & VBA.Space$(1) & VBA.Error & VBA.Space$(1) & "occured in Procedure iErrorHandler in Module ModErrorHandler", _
         vbOKOnly + vbCritical, "Error in Application"
    Resume Err_Exit
    
End Function

The error handler first checks the registry settings and allows me to break into the code in debug mode by returning a value of 1. Otherwise it lets the user input ignore, retry, or cancel for each error encountered.

A large amount of credit to my mate Alan Westwood for his help with creating this.

Is this the way that an error handler should work?! Or am I overly complicating things? Everyone talks about them but I haven't seen an in-depth example before.

Any constructive comments gladly received.

Cheers,

J.
 

chriswies

Registered User.
Local time
Today, 23:27
Joined
Nov 30, 2005
Messages
16
I like it.
From my point of view, this kind of error trapping is appropiate for commercial databases. It's worth doing this work.
I especially like the way you do different actions using the iError constants. This will definitley be used in my current project, thanks.

btw, my error trapping is beeing done the same way.
* private module constant
* procedure constant
both of them being passed to the error-function along with the err.number and err.description.

So, no additions, I just like it the way you do it.
I am currently thinking about an ErrorClass not only trapping but also writing the error including machine name, user name, time, ... and error information into an error-table which will be synchronized so I can check what happend on the users laptops. But this is still an idea.

Christoph
 

Jibbadiah

James
Local time
Tomorrow, 07:27
Joined
May 19, 2005
Messages
282
Christoph,

Thanks for the feedback.

I like your idea of an error-trapping table.

After thorough testing on my pc, I still find that users encounter different errors due to their environment or the way they approach things. Often it may just be a matter of waiting for an external action to complete. When they click 'retry' and the code continues to work... I never hear about the problem - so the table would be ideal.

It would be nice to trap the specific line of code that causes the error... any ideas on getting this detail?

Further, I think it would be useful to add a comment to explain the resolution to each problem encountered... this will allow easier resolution of future problems for different users.

Thanks again,

J.
 

chriswies

Registered User.
Local time
Today, 23:27
Joined
Nov 30, 2005
Messages
16
Jibbadiah said:
It would be nice to trap the specific line of code that causes the error... any ideas on getting this detail?
J.

http://www.fmsinc.com/tpapers/vbacode/Debug.asp
Search for 'Track line numbers to pinpoint the location of a crash' on the site.
Of course, you need their tool to add the line number.
But believe me, their tools are worth every Cent you pay!

Christoph
 

Jibbadiah

James
Local time
Tomorrow, 07:27
Joined
May 19, 2005
Messages
282
Nice link.

Thanks mate... one of the best I have seen, good detail and explanations.

Will have a thorough look and see if I can learn a little more.

Nice one!!
 

tkpstock

Cubicle Warrior
Local time
Today, 17:27
Joined
Feb 25, 2005
Messages
206
your thread has disappeared since the website was hacked.
What is this about? Does this explain why I'm getting copious amounts of spam at my work address?
 

modest

Registered User.
Local time
Today, 17:27
Joined
Jan 4, 2005
Messages
1,220
tkpstock said:
What is this about? Does this explain why I'm getting copious amounts of spam at my work address?
The forum was recently cracked/hacked. As a result a numerous amount of files were deleted. I'm sad to say that a lot of my sample database have diappeared, including a sample error-handler routine.
 

ghudson

Registered User.
Local time
Today, 17:27
Joined
Jun 8, 2002
Messages
6,194
Writing the errors to a table is a must for any developer. This should point you in the right direction on how to do it. Adjust the field names to meet your needs.

Code:
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
        
    Set db = CurrentDb
    Set rs = db.OpenRecordset("tblApplicationErrors", dbOpenDynaset, dbAppendOnly)
        
    With rs
        .AddNew
        .Fields("User") = CurrentUser()
        .Fields("NetworkID") = Environ("UserName")
        .Fields("DateTime") = Now()
        .Fields("ApplicationName") = gcProgram
        .Fields("FileName") = Dir(CurrentDb.Name)
        .Fields("ObjectName") = cObject
        .Fields("Procedure") = cProcedure
        .Fields("ErrorNumber") = lngError
        .Fields("Description") = Left$(sErrorDesc, 255)
        .Update
        .Close
    End With
        
    Set rs = Nothing
    Set db = Nothing
You could also write the runtime error information to a text file. Alert the user that an error has occured and give them the directions to email the error [text file] to you [the programmer].
 

Users who are viewing this thread

Top Bottom