raising custom errors and recording them down

delikedi

Registered User.
Local time
Today, 15:01
Joined
Apr 4, 2012
Messages
87
Hello,

I conscientiously follow the advice of programmers I trust and avoid incorporating errors as part of application logic. I have a generalized error handler whose main purpose is to record the error to the errors table, and I treat that error as a flaw in "error prevention" and modify my code accordingly.

However, with increasing frequency, I find myself in a position where I throw an "Unknown error occured. Nothing to do." kind of message to the user. These are very rare, but when they happen, valuable info pertaining to the logical flaws of my application are lost. I would like to raise custom errors with designated numbers whose custom descriptions would be looked up from a table. I believe err.raise method is the way to go, but I'm confused after reading its documentation. My current errors table, which is entirely filled with system errors, has records with err.number outside the range of 0-65535. And there are also records whose numbers are between 513-65535, which is a range that is said to be reserved for custom errors.

My programming skills are not enough for creating my custom objects, so if I am in a class module, that class module belongs to an access form or report.

How do you handle this problem?
 
I am not exactly sure what you are actually facing, so I will inject some misc points.

If you are trapping only vendor raised errors, then a proper error handler should be able to produce for you detailed logs such as this...

Example of Centralized Error Logging
http://www.access-programmers.co.uk/forums/showthread.php?t=230291#post1175164

If you are truly raising custom errors, then shame on you for not defining completely enough why your program raised the error in the first place! :cool:

Error handling need not be class based, a shared / global Module is sufficient.

And I can not locate a forum post where I have shared my standard error handling function, so I will paste the template I work from here:

Code:
Public Function DeleteLinkByAOEAOEStationID() [COLOR=Blue]As Boolean[/COLOR]
On Error GoTo Err_DeleteLinkByAOEAOEStationID

  'LOC's of function here

  'Good return code
  DeleteLinkByAOEAOEStationID = [COLOR=Blue]True[/COLOR]

Exit_DeleteLinkByAOEAOEStationID:
  Exit Function

Err_DeleteLinkByAOEAOEStationID:
  Call errorhandler_MsgBox("Class: clsObjAOEStationAOESWLinkTbl, Function: DeleteLinkByAOEAOEStationID()")
  DeleteLinkByAOEAOEStationID = [COLOR=Blue]False[/COLOR]
  Resume Exit_DeleteLinkByAOEAOEStationID

End Function
Obviously change the return data type to be appropriate for your specific use.
 
Ty for your reply, mdlueck.
My error handler routine is very similar to yours.
Where you invoke the line
Code:
Call errorhandler_MsgBox
I also invoke a function call:
Code:
Call RecordError(strProcName, Err.Number, Err.Source, Err.Description)
which basically is an append query that writes the arguments into the columns of the errors table.

it is exactly at this point that I would like the error to be of my design. Instead of err.number=91, I want to pass err.number=92. And instead of "
Object variable or with block variable not set" I want to pass "The user tried to do [this]. Curious how he managed to even try, after all my safeguards". And I would like these arguments to be looked up from a table of "Custom errors".
 
I want to pass "The user tried to do [this]. Curious how he managed to even try, after all my safeguards". And I would like these arguments to be looked up from a table of "Custom errors".

I do not know if I have yet created a truly custom error with all of the details filled in.

I have custom errors, pass a custom message through to my standard error handler, and thus it gets logged. I do not worry that supporting fields are therefor bogus for my custom log messages. The custom message text explains why what was logged was logged. Example:

Code:
  'Make sure that the string is within the limit of the Stored Procedure Parameter length
  If Len(strFindText) > 50 Then
    Me.fldSearch.BackColor = vbRed
    Call errorhandler_MsgBox("Form: Form_aoepfmeaassociate, Subroutine: btnSearch_Click()"[B][COLOR=Blue] & errorhandler_AOESearchStringTooLong()[/COLOR][/B])
    GoTo Exit_btnSearch_Click
  End If
Which relies on...

Code:
'Specific message text stating that the search string is too long...
Function errorhandler_AOESearchStringTooLong() As String

  errorhandler_AOESearchStringTooLong = vbCrLf & "Please limit your search criteria to a maximum length of 50 characters."

End Function
So that is how I have extended my standard error handler to be customizable. I just do not raise a custom error and have the generic handler handle it.
 
I see your point about customizing error messages. However my problem is more about errors that I can't foresee. For example, in an If...ElseIf...Else block (or a select case block for that matter) I do my best to handle all possible outcomes of the logic, however et the end, after the statement "Else" or "Case Else" I find myself unable to write anything but a disfunctional
Code:
msgbox "Unknown error occured, contact admin"
At such times, I would like to use the err.raise method to raise a custom error that would get logged, Instead of the user having to contact me.
 
When you raise an error you designate the number and description. You can use a function to get this information out of a table.

Once the error is raised the code continues to be processed exactly as it would in a normally generated error condition.

I suspect you are looking for something you imagine is more complicated.
 
Delikedi.

May I suggest that your time would be better spent on preventing errors rather than trying to write those errors to a table?

For example:-

This next line is somewhat meaningless if we can’t see the Function or Subroutine being called.

Call RecordError(strProcName, Err.Number, Err.Source, Err.Description)

1. What we don’t know is what happens if that Function or Subroutine raises its own error.
2. Why is it a Function if the Function’s return value is not being used?
3. If the original error can’t be predicted then how are you going to handle it?
4. How do you turn it off during development?
5. If the error log table is in the backend then what happens on network failure?
6. What do you do if the error is raised because of a missing reference?
7. 8. 9. 10. 11…

The whole thing is a can of worms which, over the years, has lead me to believe that any global error handling procedure needs to be the most bullet proof procedure in the front end. The more functionality we add to the global error handler the more chance of that code failing.

I’ve been using pretty much the same global error handler for about 12 years, but it’s still not perfect.

My current thinking is this…
An error, as reported by a global error handler, is by its very nature unknown, otherwise it would have been fixed. Continuing to process data after an unknown error puts the data at risk. Therefore, in order to protect the data in the database, an unknown error should cause the front end to shut down immediately after simply displaying the error. Nothing fancy, simply display the error and quit.

Chris.
 
Thank you for your input, Galaxiom and ChrisO.

@ChrisO
I fully agree with your approach, error prevention is my foremost concern. When an error gets recorded in the errors table, I treat it as something that should never get recorded again in the future. The global error handler is just a last resort, to capture the errors that manage to slip through all the validation routines in my code.

An example is this: when a user adds a new record, that record obtains an autonumber PK that has to be inserted as a FK in multiple tables down the hierarchy of the database. For example, filling the contact name and telephone number of a simple data entry form affects a total of at least 5 tables in my database (I may have over-normalized but bear with me). I use functions to perform the record entry to relevant tables. When each function executes successfully, they return the boolean value of true, and most of the time they do. But when the don't, for any conceivable reason, I would like that problem to be recorded, instead of just throwing an "unknown error occured" at the user. Note that no technical error occurs in the above scenario.

@Galaxiom
You may be on point about me over-complicating things. But whenever I considered building such a table, I felt confused about what error codes to give, whether those error codes collide with system error numbers, how to use the vbObjectError constant etc. So I felt the need to ask how professionals do it.
 

Users who are viewing this thread

Back
Top Bottom