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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Detecting errors with ON ERROR 1

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB
I have a substantial application in which there are occasionally errors – my errors! To deal with this I have a function which is invoked by an ON ERROR instruction at the start of the application.

This ‘ON ERROR’ instruction effectively calls an ErrorRoutine() function with ERROR(), MESSAGE(), PROGRAM(), LINENO()

Once there, ErrorRoutine() examines the call stack with ASTACKINFO(), finds the user name, what tables were open &c, and generates (among other things) an entry in the Errorlog.txt file with this information. So, as the developer, I can examine the Errorlog.txt file and - if necessary – make corrections to the code. This usually works fine.

However, I have been finding that sometimes The ‘ON ERROR’ routine is not being invoked : instead the user sees a message which I imagine is generated by VFP - something like :

Code:
Program Error
     Error reading file s:\data\xsupp.dbf
    |Cancel|     |Ignore|    |Help|

I am trying to determine why this is happening (rather than invoking my ErrorRoutine). Unfortunately I have not been able to replicate the error myself, but the user has kindly sent me a screen shot on the last occasion.

One issue could certainly be that there are places in the application where the TRY . . . . CATCH TO . . . . . ENDTRY construct is used. And my understanding is that this takes precedence over the ON ERROR command for the time being. Would this be the only occasion where a run-time error would not cause the ErrorRoutine to be invoked?

I have noticed that when the above situation arises (an error only being reported by VFP), the ON ERROR command is still lurking in the background : because when the user – understandably ! – eventually clicks on Cancel, my ON ERROR instruction is invoked, but fails, because it says it cannot find the ErrorRoutine() function. I suppose I could help myself in this matter by including a simple instruction :

Code:
   ON ERROR MESSAGEBOX(MESSAGE() + CHR(13) + PROGRAM() + CHR(13) + ;
            "Line " + STR(LINENO(), 3))

. . but then I would not be getting the benefit of the more detailed stack analysis that ErrorRoutine() provides.

However my first question to the helpful members here is “Is the TRY . . . CATCH construct the only one which temporarily over-rides the ON ERROR statement”.

Thank you
 
Andrew, the short answer is No. The Error event also overrides ON ERROR. The ERROR event is an event in every object, and fires when an error occurs in that object's code.

But that's not really the point. If your user is seeing a VFP error message (with Cancel, Ignore, Help buttons), that does not indicate that the ON ERROR routine is being overridden, but rather that it has not yet come into force. In other words, you have not yet executed [tt]ON ERROR DO ... WITH ...[/tt], or alternatively, you have executed that command, but you have since executed [tt]ON ERROR[/tt] by itself.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
That ErrorRoutine isn't available also points out you don't keep the reference to it in SET('PROCEDDURE').
The simplest way this never can happen is to put a function ErrorRoutine in the main.prg

As Mike said not only TRY...CATCH but also an Error method can override the global ON ERROR handling. You usually want that, especially in case of TRY..CATCH, where you'll do some specific handling, usually. The other thing that can cause prompts for files is SET TABLEPROMPT OFF, you should have that, and there are a few other things for SQL Passthrough Login dialogs. Only when all of that is turned off handling goes through ON ERROR for missing files or when connection problems occur.

Chriss
 
While I don't think this is the case here, worth noting that you also get the default VFP error handler when there's an error in your error handler.

Tamar
 
I don't know as much as my colleagues here about error handling in this context, but I do know there are some situations that are very
hard to trap and handle - and you've hit a key one.

The error you have shown is almost certainly a networking error, either an infrastructure one - cabling, switches, hubs, or NICS - or
a server problem - maybe it just needs rebooting.

I had a client with the same message last week, where he had clients that could map drives to his server, could see data in explorer
but when VFP tried to access files he got the same message you do - turned out his IT had upgraded the copy of Office that runs on the
server (not the client, there are 'scanners' on the server that process spreadsheets for reports stuff like that) and it had not been
rebooted. Clients could startup, log in, get maps and they would not read in VFP. The fix was easy, reboot server, reboot workstations,
remap drives, and bingo - all was well.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Andrew,

You can check to see if your ON ERROR routine is in force by caling ON("ERROR"). It should return the command that invokes the error routine. If it returns an empty string, it means that no such routine is active.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you for all your replies.

Mike (The ON ERROR instruction was issued at the start of the application so was still in force unless superseded).

Thank you for pointing out that a form’s Error() method can over-ride the ON ERROR command. I do in fact have a very few forms which have code in their Error() methods - mainly for forms which invoke things like Microsoft Office. But I do not believe that this was the cause of the problem in this case.

So I have amended my notes to say that – until it is superseded by another ON ERROR statement - the original ON ERROR statement remains in force except when temporarily over-ridden by a form’s Error() method or by a TRY . . . .CATCH sequence. Hope that is correct!

Chris Thank you for pointing out that I might need to include my Errorroutine.prg in the SET PROCEDURE instruction in my startup (main.prg) program. I do have a SET PROCEDURE command, but had not included my “ErrorRoutine.prg”. Despite that, the ON ERROR command was effective in most cases and managed to call that routine and generate the Error log &c. Don’t know why.

But I will follow your guidance and include the instruction SET PROCEDURE TO {generalProcs &c] , Errorroutine. It might help !

Tamar Errors in my ON ERROR code. Thanks for pointing that out. In fact I had discovered that by mistake only yesterday as I was experimenting with a different On ERROR statement. That seems to be a speciality of mine - errors in the error reporting procedure . . .

I will keep an eye on this and will see whether modification to SET PROCEDURE improves matters.

Thanks again. Andrew
 
No, instead of SET PROCEDURE TO a separate PRG, have that code withiin main.prg at its end and it'll always be found, even if any code (including third party code) tidies up with things like SET PROCEDURE or CLEAR or RELEASE commands.
And for the specific error you fail to log, I think it's a case SET TABLEPROMPT OFF will help. Because when you read that topic you'll see a non found file, a network error or a file corruption or addressing a non-existant alias, any glitch of these kinds VFP tries to resolve by asking for a file instead of triggering the error routine.

Chriss
 
will see whether modification to SET PROCEDURE improves matters.

By all means do that, Andrew. But I have to say that I have never needed to include my error routine in a SET PROCEDURE. The error routine is in its own PRG, which is on the VFP search path. So VFP is almost guaranteed to find it.

If you issue an ON ERROR which references a file or a procedure that VFP cannot find, you won't get an error message at the point (at the time that you issue ON ERROR). However, when any subsequent error occurs, you will get a "File does not exist" error.

Anyway, good to see that you have tracked it down.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

even simpler, once all is in an EXE the path to ErrouRoutine.prg won't matter. Still, anything you want to be sure of being found is best always kept on the callstack, and that's all code within main.prg
Thinking about it, the files compiled into an EXE will always be found by VFP, the EXE itself is always prioritized. So it points out these are error like not found tables that you have to guide to the error handling by not allowing tablepromts to circumvent error handling.

There are more reasons error handling could not occur, mentioned in how SET REPROCESS is set in its topic.

And I can also imagine Griffs situation colliding with TABLEPROMPT behavior to promt for a table instead of raising an error event. Usually such things are only useful for a developer, not for an end user. If dbfs are not found, it's a case for logging that problem and not for letting a user guess which file the EXE wants. Given that he could choose any file you can't even predict what happes with it.

Chriss
 
I want to add my voice to say that I've never need SET PROCEDURE for an error handler. (In fact, I do my very best not to use SET PROCEDURE at all. I think procedure files are evil. I wrote about that and how to get rid of them here:
Unless your error handler is in a procedure file, I can't imagine a situation where your ON ERROR command works, but the program can't be found when needed.

Tamar
 
Chris, of course you are right about the error routine being bound into the EXE. I don't know why I even mentioned it being on the search path.

But, as I mentioned earlier, it's clear that Andrew's problem was not caused by a failure to find the error routine. If it had, the error message would have indicated that.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
What has been happening is that on some occasions an error has happened (while running my application), and for some reason my ON ERROR instruction is not being invoked, but instead I am getting what I believe is a default VFP error message, offering the option Cancel | Ignore | Help.

The user then (eventually) tries to close the application (by clicking on the X at the top right of the screen). This invokes an instruction which was executed at the start of the application :

ON SHUTDOWN Do SystemExit

At this stage my ON ERROR code is invoked. It enters my ErrorRoutine.prg which reports :

File systemexit.prg does not exist.

(Systemexit is my program which makes sure all files are closed &c). I know that Errorroutine.prg is being invoked at this stage, because I have modified the code to include advice that (when the error mention Systemexit) the user should take a screenshot and give me a call or send me an email, and this appears on the screenshot.

But thank you all for your interest and advice!
 
That can only happen, when users run VFP9.exe and source code or DO an EXE. Are you not building an EXE?

Chriss
 
Thanks Chris

The users on this site are running a built .exe file (about 4.3 MB - I created it by clicking Build in the project manager). These errors are both happening (occasionally) when the user is running the application on his site.

- But I have not had the problem in my office. I do occasionally run the .exe against a copy of his data, as well as running in the development environment.

I agree, it does seem strange. In the example I quoted, an error has occurred on the user's site, but for some reason my ON ERROR statement is not being executed (that might be for the reasons we have discussed, but I am surprised). Then, when the user exits (I am pretty sure he will have clicked on the X), it cannot find the code specified (at the start of the session) by my ON SHUTDOWN DO SystemExit code. My Systemexit() code is part of my main.prg.

But then - surprisingly, my ON ERROR code does kick in, and (for this error) executes my MESSAGEBOX with a request to give me a call - which my patient user does!

 
If that's happening in an EXE, now please try the steps I recommended already:
Having ErrorRoutine code in your main.prg
NOw also put your systemexit code there.

So instead of having seperate PRGs put this into the main.prg. It's a well known recipe such routines always are on the stack, thus always available.

Since not even your systemexit.prg is found, the likely rreason is some CLEAR (ALL or anything special) or RELEASE commands and anything releasing the ON('ERROR') setting, which often was done befoe TRY..CATCH existed to have something like ON ERROR plError = .t. and then to handle such an error with IF plError - like you can now do with the CATCH block. When finally the ON ERROR isn't reset to the general error handling what you see dan happen. So these temporary changes of the global ON ERROR setting have to be done very precise to always reset the general error handling.



Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top