Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Error handling problem 6

Status
Not open for further replies.

jbrowne

Programmer
Feb 1, 2000
182
IE
Hi,

I have a problem in that my application on occasion crashes out - without error handling catching the error. Obviously this looks very unprofessional to my users when it happens. On most occasions (but not always) it is a 3021 error - 'No current record'. It happens when I do a seek or a movefirst on a table which has no records or that I haven't got a hit on. In most cases in my project I try to overcome this by checking for a nomatch or by checking the recordcount property(which I've found to be buggy by the way) but every now and again there is no check or error handler and up pops the error and crash goes the system. My question is - is there a way of doing some sort of a global error trap so that I could at least pop up a better message to the user that something serious has gone wrong and to contact support instead of the application just falling over with an untrapped VB error. Up until now all my error trapping has been within the procedure itself. Is it possible to trap errors at form level or better yet at MDIForm level (I am using an MDIForm in this project and 99% of my forms would be children to this.

Any suggestions would be greatly appreciated
John B
 
2 parts to this...

1) to prevent a no current record, the most reliable way (I havbe found) is to check that
one of both BOF or EOF are false. ie if they are both true, it is an empty recordset

thus
Code:
if rs.BOF and rs.EOF then
' ooops empty recordset
else
'process records as expected
end if

part2, unhandled errors are passed up the call stack, so you could have one single error handler per form. I believe that in a function that handles some errors, you can re-raise the error to be handled by the error handler above (in stack)


Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Plus you can use self-defined error handlers (per module):
Code:
Sub whatever()
[blue]OnError goto Err_whatever[/blue]
Dim dim dimmer...
code

Exit Sub
Err_whatever:
msgbox "Almost crashed again! :-]"
Err.clear
Resume Next

End Sub

Besides the little jokes up there, this code is serious.. ;-)
MakeItSo

Andreas Galambos
EDP / Technical Support Specialist
(andreas.galambos@bowneglobal.de)
HP:
 
Thanks for your prompt reply guys,

Firstly Matt - I have already twigged the bof and eof check instead of recordcount - it works well - but in the case of a nomatch not being checked for on a seek - I still get the 3021 error. I know that the proper way is always do the bof/eof check before doing anything with the table and check for hits before interacting with a record but - the project I am working on is reasonable big (over 150 forms and 40 modules) To go through each one would be very time consuming. The application is quite stable - just every now and then I get these unforseen errors.
Which takes me on to point 2. You say that I can have a single error handler per form. How does this work ? As I understand it the error handler has to exist within a procedure so where to I put it - form_load ?
The structure that 'MakeItSo' (cool name by the way - you Next Generation fan - you) gives above is the general error handler structure that I use within all my procedures - the problem I have is that if the error goes into the the errorhandler and I am not specifically dealing with that error then it crashes - can you have an all powerful error handler which then comes in to play for the form itself and it takes over preventing the crash - or am I off the mark altogether. I don't want to have to revisit every error handler in my project and try to deal with this specific error - and as I say occasionally other errors have crashed the system too.
I hope I am making myself clear - any more suggestions ?

John B
 
Open a new project, add this code to the form and a command button, I call it the 'Pin Point The Error' routine. It will also create an error.log in the app.path...

Option Explicit

Dim bStopErrorMsg As Boolean

Private Sub Command1_Click()

On Error GoTo Command1_Click_ErrorControl

10 Kill "C:\YouDontHaveThis.txt"
20 MsgBox "continued operations"

30 Err.Clear
Command1_Click_ErrorControl:
40 If Err <> 0 Then
50 Select Case ErrorLogAndStop(Err.Number, Err.Description, Erl, Err.Source, &quot;{Form1}&quot;, &quot;{Command1_Click}&quot;, &quot;{method-desc}&quot;)
Case vbRetry: Resume
Case vbIgnore: Resume Next
60 End Select
70 End If
On Error GoTo 0
End Sub

Public Function ErrorLogAndStop(ErrNum As Long, _
ErrDescription As String, _
ErrLine As Long, _
ErrSource As String, _
sModuleName As String, _
sMethodName As String, _
sMethodDesc As String) As Long

Dim Msg As String
Dim intFreeFile As Integer
Dim sPath As String
On Error GoTo ErrLogErr

Msg = ErrSource & &quot; Caused An Error. &quot; & &quot;Error Description = &quot; & ErrDescription & _
&quot;. Error Number = &quot; & ErrNum & vbCrLf & vbCrLf & _
&quot;In Module: &quot; & sModuleName & &quot;. Procedure: &quot; & sMethodName & _
&quot;. At Line No: &quot; & ErrLine & &quot;.&quot; _
& vbCrLf & vbCrLf & _
&quot;ExePath = &quot; & App.Path & &quot;\&quot; & App.EXEName & vbCrLf & _
&quot;(App Version = &quot; & App.Major & &quot;.&quot; & App.Minor & &quot;.&quot; & App.Revision & &quot;)&quot; & vbCrLf & _
vbCrLf

If Not bStopErrorMsg Then 'No Messaging
ErrorLogAndStop = MsgBox( _
Msg, vbAbortRetryIgnore + vbMsgBoxHelpButton + vbCritical, _
&quot;What to you want to do?&quot;) ', _
' Error.HelpFile, _
' Error.HelpContext)
Select Case ErrorLogAndStop
Case vbAbort
sPath = MsgBox(&quot;Turn Off Error Messaging in the current AppRunning Period ?&quot; & vbCrLf & vbCrLf & _
&quot;Note: This Will Automatically Handle Errors Without Messaging.&quot;, vbYesNo + vbQuestion, &quot;No More Error Messages In &quot; & App.Title & &quot; For the time being ?&quot;)
If sPath = vbYes Then bStopErrorMsg = True
End Select
End If

intFreeFile = FreeFile
sPath = App.Path & &quot;\&quot; & &quot;Error.log&quot; ' If Not Exists Then Create
Open sPath For Append As #intFreeFile
Print #intFreeFile, Msg
Close #intFreeFile

Exit Function
ErrLogErr:
200 MsgBox &quot;Error LogFile Process Not Successful, cause of &quot; & CStr(Err.Number) & &quot; &quot; & Err.Description

End Function
 
Ok - thats very interesting and certainly useful. The only problem I have is as I see it is - I would still have to go through all of my error handling routines in each procedure and put this is as an &quot;ELSE&quot; to the specific error handling that I have already - is this correct ??

John B
 
Yes you would have to put it in each procedure, you dont have to add any extra error handling unless you want a specific event to occur with a certain error. Can you use something like MZTools and customize a script to be inserted into each procedure? I use my own vb add-in to do this for me so I'm not sure.
 
Thanks LPlate, you've been a good help - its unfortunate that I still have to wade thru every procedure in every form and module but if thats the way it has to be so be it.
Again thanks to all for your suggestions

John B
 
Keep in mind you only need to add it in the procedures that are troubling you, not all, just one if you like.

I hope it helps you correct your error! & thanks for the star.

g/l
 
A possible worthwhile investment for the future would be to write an add-in that automates the insertion of error handling in routines and save the manual effort. By including in each routine, the error handler can report the name of the routine when reporting the error - which helps the job of debugging consdirably when the error is reported by a user. You can set up the add-in to insert the error handler in the current procedure, the current form/module or the entire project.

 
OK the problem I have is that the errors coming back are in areas where the error handler doesn't reference the specific error thrown therefore it doesn't handle it so it falls over OR there is no error handler at all for the specific procedure that the problem is with. For that reason I am thinking that I do need to insert the above code in every procedure of every form (I need to be sure that I've completely solved this 'fall over' problem. As I've mentioned before the project I am working on is quite large so I wanted to avoid going back thru it all manually.
Is it possible 'Glasgow' to write an addin to put in the above error trapping in all procedures in the current project bearing in mind that there is error handling already (which I need to keep there) in the majority of procedures. If it is possible - can you give me pointers as how to go about doing this as I have never used the add-ins that you mention.

Thanks
John B
 
> OK the problem I have is that the errors coming back are in areas where the error handler doesn't reference the specific error thrown therefore it doesn't handle it so it falls over...

Show us a couple of typical examples of your error handling
 
I'm no expert but...

An add-in has to be done as a separate project - just select AddIn when you create the new project. The documentation covers the topic. Create a User Document (form) that will ultimately be visible from your other VB projects. Add command buttons or radio/option buttons for the three options (current procedure, current module and entire project) with appropriate code behind each. Use the CodeModule object together with ProcofLine, DeleteLines, InsertLines, ProcBodyLine etc to manipulate the code. If this project is open when you open your development project it will be available as an add-in (although ultimately you will build DLL) and you can test the two together. You can include code in the new project to exclude routines with specific names which you want to ignore or extend the logic to check for existing error traps and ignore such routines. As the bulk of my code is in subroutines & functions called from standard events etc, I exclude all routines with underscores in the name - which tend to be the 'standard' routines within which I tend to have very little actual code.

This approach does take some thought and it is not necessarily easy to get it bulletproof. I add a recognisable comment (see below) to any lines added by the add-in so that they can easily be identified, removed and replaced - either manually or by the errortrap insert process itself. An example of resulting code (which includes an auto-inserted trace capability) is shown below


Private Sub LfnFormUnload()
If ErrTrap Then On Error GoTo LfnFormUnloadErr 'Auto ErrIns - Do not modify 30/05/03
If Trace Then GmsTrace &quot;LfnFormUnload&quot;, TraceOn 'Auto ErrIns - Do not modify 30/05/03
Set rsMain = Nothing
If Parent.Name <> Me.Name Then GfmParentReturn Fm, Parent.chkCdy
If Trace Then GmsTrace &quot;LfnFormUnload&quot;, TraceOff 'Auto ErrIns - Do not modify 30/05/03
Exit Sub 'Auto ErrIns - Do not modify 30/05/03
LfnFormUnloadErr: 'Auto ErrIns - Do not modify 30/05/03
GmsErrorTrap Err, &quot;LfnFormUnload&quot; 'Auto ErrIns - Do not modify 30/05/03
End Sub

The GmsErrorTrap routine handles and reports the actual error and is passed the name of the routine in question.

Hope that helps with a starting point - not easy but I have found the effort to be worth it.

 
Sorry LPlate - I probably didn't make myself clear that time. When I said -
&quot;OK the problem I have is that the errors coming back are in areas where the error handler doesn't reference the specific error thrown therefore it doesn't handle it so it falls over...&quot;
I meant before inserting your code in everywhere. Any error handlng that I have in up until this handles specific error numbers - your code will deal with the rest.
The point I was trying to make is that I will have to spend time inserting your code into every routine (that could be up to a weeks work) and I was wondering if the was a way of doing this more quickly by usig the addins that Glasgow was talking about.

 
Thanks for the response Glasgow - its another option for me to explore anyway.
 
jbrowne As Glasgow suggested, start a new project and select 'Addin' instead of standard exe, run the Addin.

Open up a second instance of vb and open any project.

Now in the vbide menu(of the second project), go to Addin's and click 'My Addin'

Presto! Your addin will appear.

Now all you have to do is code the functions you require.
 
If you want to do it the easy way then download MZTools from :


It's free, and used by many of this forums gurus.

It has a routine which adds an error handler in any required procedure. The error handler skeleton is preset and user configurable.

MZTools also has lots of other goodies built in!

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'If we're supposed to work in Hex, why have we only got A fingers?'
 
Oh to be a guru! Instead I prefer to concentrate my efforts on wheel re-invention - a very satisfying if time consuming occupation.

I did learn from the process and add-ins no longer scare me the way I used to so, although the MZTools route would be a good one for jbrowne to explore, I can at least echo the senitiments of the late Mr Sinatra - 'I did it my way'. Modifying the lyrics to say 'someone else did it better and did it first' ruins the rhyme and doesn't have the same ring to it I feel.

johnwm - will it apply to entire module or project?
 
>have to go through all of my error handling routines in each procedure and put this is as an &quot;ELSE&quot;

Given that VB6's error handling is relatively primitive in this day and age, it is always worthwhile putting in an Else to deal with unanticipated errors, even if it just reraises the error so that it can bubble up the call stack until it finds an error handler that will deal with it...
 
I have only used it procedure by procedure - but it's only one click each - 'spose I ought to experiment when I have time.

Perhaps another user already found out?

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'If we're supposed to work in Hex, why have we only got A fingers?'
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top