Topic: Error handling at a procedure call from procedure

The people, kind all time of days! I understand, a subject most likely traveled all over, but something whether I cannot hammer in a normal context in search, whether I can that I do not catch up... , procedure is launched. In it the error handler is written: On Error Go To, the output, labels etc. From this procedure is launched the second procedure. In it too there is an own error handler. A question: at error actuating in the second procedure, the output agent fulfills from the first procedure... I Remember, apparently, Sanych said that Aks so does whether always, whether by default... And whether always? There are no variants to make so, what if an error in the first procedure its output agent, if in the second works, that, accordingly, the handler of the second?


Re: Error handling at a procedure call from procedure

I use for a long time 2 types of output agents - normal which always works in current procedure and floating which registers an error in current procedure and transfers it in caused procedure, i.e. at top level we receive the error report with call stack. The normal output agent is put in procedures of top level which immediately interact with the user, and floating - in units and classes.

Sub NormalErrors ()
On Error GoTo ErrorHandler
On Error Resume Next
Exit Sub
Resume '>> remove in release
LogError Err. Number, Err. Description, Erl, "NormalErrors", "Module1"
Resume ExitHere
End Sub
Sub BubbleError ()
On Error GoTo ErrorHandler
Exit Sub
Resume '>> remove in release
Debug. Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
Err. Raise Err. Number, "BubbleError of Module1", Err. Description AND vbCrLf AND "in BubbleError of Module1 at" AND Erl
End Sub

Resume which is never fulfilled it is necessary for debugging to pass for the line with an error, Debug. Assert - that at debugging the error did not float, and  in procedure where arose. These lines are deleted in release. There is still a pair of types of output agents, but it already details


Re: Error handling at a procedure call from procedure

MrShin, it is interesting
LogError - keeps a broad gull in the table, what such Erl?
And what else types of output agents apply? (If it not the know-how is finite)


Re: Error handling at a procedure call from procedure

Yes, LogErr saves an error in the table and displays it in the form of the message, here the text:

'//module with error handling functions
' Purpose: Generic error handler.
' Logs errors to table "ErrorLog".
' Arguments: lngErrNumber - value of Err. Number
' strErrDescription - value of err.description
' strLine - code line number (Erl) Erl=0 if no row number in the line
' strCallingProc - name of sub|function that generated the error.
' strCallingModule - name of code module that generated the error.
' vParameters - optional string: List of parameters to record.
' bShowUser - optional boolean: If False, suppresses display.
Function LogError (ByVal lngErrNumber As Long, ByVal strErrDescription As String, strLine As String, _
strCallingProc As String, Optional strCallingModule As String, Optional vParameters = "{Missing}", Optional bShowUser As Boolean = True) As Boolean
On Error GoTo Err_LogError
Dim strMsg As String ' String for display in MsgBox
Dim rst As DAO.Recordset ' The Aph_tblErrorLog table
Select Case lngErrNumber
Case 0
Debug. Print strCallingProc AND "called error 0."
Case 2501 ' Cancelled
' Do nothing.
' Case 3314, 2101, 2115 ' Can't save.
' If bShowUser Then
' strMsg = "Record cannot be saved at this time." AND vbCrLf AND "Complete the entry, or press <Esc> to undo."
' MsgBox strMsg, vbExclamation, "Error"
' End If
Case Else
If bShowUser Then
strMsg = "Error" AND lngErrNumber AND ":" BOTH strErrDescription AND vbCrLf AND "in" AND _
strCallingProc AND "of" AND strCallingModule AND "at" AND strLine
Interaction. MsgBox strMsg, vbExclamation, "Error" AND Now ()
End If
' log the error to database
Set rst = CurrentDb. OpenRecordset ("tbl_ErrorLog", dbAppendOnly)
rst. AddNew
rst! [ErrorNum] = lngErrNumber
rst! [ErrorDescription] = Left $ (strErrDescription, 255)
rst! [ErrLine] = strLine
rst! [CallingProc] = strCallingProc
rst! [Module] = strCallingModule
rst! [CreatedTimeStamp] = Now ()
rst! [UserName] = GetCurrentUserID ()
If Not IsMissing (vParameters) Then
rst! [Parameters] = Left (vParameters, 255)
End If
rst. Update
rst. Close
LogError = True
End Select
Set rst = Nothing
Exit Function
strMsg = "An unexpected situation arose in your program." BOTH vbCrLf AND _
"Please write down the following details:" BOTH vbCrLf AND vbCrLf AND _
"Calling Proc:" BOTH strCallingProc AND vbCrLf AND _
"Error Number" AND lngErrNumber AND "in line" BOTH strLine AND vbCrLf AND strErrDescription AND vbCrLf AND vbCrLf AND _
"Unable to record because Error" AND Err. Number AND "in line" BOTH Erl AND vbCrLf AND Err. Description
Interaction. MsgBox strMsg, vbCritical, "LogError ()"
Resume Exit_LogError
End Function

Erl is number of a line, Erl it is not equal to zero, only if the line with an error is enumerated in the code, I use MZ-Tools for numbering in all units and in certain cases the I use a numerator on VBA, but MZ-Tools works faster, in mine not all bugs are caught - if some times to add numbers and to remove, which-in indents what place are broken, all do not reach hands to complete.
One more useful output agent - floating with the final code:

Sub BubbleWithFinal ()
On Error GoTo ErrorHandler
On Error Resume Next
' here we place the code which fulfills anyway, closing  and corrupting of variables is normal
Dim err_num As Long, err_descr As String, err_ln As String
If Len (err_descr)> 0 Then GoTo ErrorRaise
Exit Sub
Resume '>> remove in release
err_num = Err. Number: err_descr = Err. Description: err_ln = Erl
Debug. Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
Resume ExitHere
ErrorRaise: On Error GoTo 0
Err. Raise err_num, "BubbleWithFinal of Module1", err_descr AND vbCrLf AND "in BubbleWithFinal of Module1 at" AND err_ln
End Sub

There are still modifications, but they are already ground under specific applications, idea in them the same.
Output agents are generated MZ-Tools by one button, very conveniently. I do not put handlers only in the most simple procedures of type of reset of value of a normal variable, in remaining where in essence there can be an error, always I put the handler.


Re: Error handling at a procedure call from procedure

Yes, STOP_AT_ERROR and IS_DEV - simply global  the constants, the first includes a stop in the pop-up output agents, the second - if True application in is a development mode, is used not only in output agents, but also other places of the code for simplification of debugging. Performance does not stop anyway, if IS_DEV = False.


Re: Error handling at a procedure call from procedure

MrShin, thanks! I will try "pop-up" to use in the code. (About Erl not smile