Solved

on error handling Visual Foxpro

Posted on 2011-09-06
7
1,121 Views
Last Modified: 2012-05-12
I'm trying to setup an error handling routine.
I have tried to set up a simple "On Error do MyerrorHandler" at the begining of my main program. Then I create a simple error condition changing the name of a VFox table to get a run time error and activate the MyErrorHandler. Nevertheless the on error code doesn't execute.
If I follow the Try Catch approach how sould I proceed.
Kind regards
Lucilia C
0
Comment
Question by:luciliacoelho
7 Comments
 
LVL 27

Accepted Solution

by:
CaptainCyril earned 500 total points
ID: 36493431
TRY CATCH is good for short trapping.

You should use
ON ERROR DO errorhandler WITH ERROR(), MESSAGE(), MESSAGE(1), PROGRAM(), PROGRAM(1), LINE(), LINE(1)

However if it is not working that means you have an ON ERROR which resets it somewhere after you initialize it. What is exactly not working?

Try to put a MESSAGEBOX in the handler. Try to put a MESSAGEBOX(ON('ERROR')) elsewhere in the code to see if the trap is still initialized.
0
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 36493703
As Cyril says, you were on the right track, but somehow either you chnaged a table name your code does not work on or the on error is reset somewhere. TRY CATCH is not meant for global error handling, it's just there to catch expected errors locally.

The "MyerrorHandler" must either be a prg on it's own, you set procedure to, before on error, and that procedure must stay known throughout the lifetime of the application, it's really better to make a procudure in the main.prg file, as it's safe, it's always on the call stack.

If you ant to test your error handling simply add a line of total rubbish, like:
lcCode = "sdljfsjdgsfkghks"
&lcCode

This compiles but errors at runtime.

Or do
USE hjkshdfgkjsfhgkh

Bye, Olaf.
0
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 36494378
Oh, and another very simple way to test error handling is to call ERROR 1 or any other defined Error number.

Bye, Olaf.
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 42

Expert Comment

by:pcelba
ID: 36494408
I am using following setup and appropriate routine - it always saves the error info into a temporary file and also to the errorlog.dbf which is later posted to the development site (this part was removed):

ON ERROR DO PrgError WITH ERROR(), SYS(16), LINENO()  && This must be at the beginning of the main program

The PrgError procedure must also be in the main program or in procedure file:
 
PROCEDURE PrgError
LPARAMETERS nError, cMethod, nLine

LOCAL lcOutFile, lcErrtext, lcAppVers, lcAppName, ldAppDate, ;
  laUsed[1], lnWarea, lnI, lnWAcount, loFormObject

lnWarea = SELECT(0)

lcOutFile = ADDBS(SYS(2023)) + SYS(2015) + '.ERR'

lcAppVers = IIF(TYPE("_screen.AppVersion")="C", _screen.AppVersion, "XXX")
lcAppName = IIF(TYPE("_screen.AppName")="C", _screen.AppName, "XXX")
ldAppDate = IIF(TYPE("_screen.AppDate")="D", _screen.AppDate, {//})

IF VARTYPE(m.gn_errCount) <> "N"
  RELEASE gn_errCount
  PUBLIC gn_errCount
  gn_errCount = 0
ENDIF

gn_errCount = m.gn_errCount + 1

TEXT TO lcErrText TEXTMERGE NOSHOW 
**********************************************************************************
<<"*"+PADC("Error log info from " + lcAppName + "  v" + lcAppVers, 80)+"*">>
**********************************************************************************
ERROR trap in  <<PROGRAM()>>   <<SYS(0)>>   <<DATETIME()>>
**********************************************************************************
Version: <<lcAppVers>>  <<ldAppDate>> 
ERROR <<nError>> in <<cMethod>>,  Line: <<nLine>> (ErrCnt <<gn_errCount>>)
<<MESSAGE()>>

Settings:
SET DATE <<SET("DATE")>>
SET CENTURY <<SET("CENTURY")>>
SET STRICTDATE TO <<SET("STRICTDATE")>>
SET COLLATE TO <<SET("COLLATE")>>
Code Page: <<CPCURRENT()>>
SET EXACT <<SET("EXACT")>>
SET ANSI <<SET("ANSI")>>
SET DATASESSION TO <<SET("DATASESSION")>>

Configuration File: (<<IIF(FILE("@:\CONFIG.FPW"), "In EXE", "On disk")>>)
<<SYS(2019)>>
Resource File: (<<SET("RESOURCE")>>)
<<SYS(2005)>>
Temporary folder: (<<LTRIM(TRANSFORM(DISKSPACE(JUSTDRIVE(SYS(2023))),'999999999999999'))>> bytes free)
<<SYS(2023)>>
Home folder: (<<LTRIM(TRANSFORM(DISKSPACE(JUSTDRIVE(HOME())),'999999999999999'))>> bytes free)
<<HOME()>>
*Data folder: (<<LTRIM(TRANSFORM(DISKSPACE(JUSTDRIVE(AppDataFolder())),'999999999999999'))>> bytes free)
*<<AppDataFolder()>>
VFP Version: (Language <<VERSION(3)>>)
<<VERSION(1)>>
OS Version:
<<OS(1) + " " + OS(5) + " " + OS(7)>>
Topmost window: <<WONTOP()>>
Active form: <<IIF(TYPE("_screen.ActiveForm.Name")= "C", _screen.ActiveForm.Name, "")>>

ENDTEXT


lcErrText = lcErrText + CHR(13)+CHR(10) + "Form list:" + CHR(13)+CHR(10)

FOR lnI = 1 TO _screen.FormCount
  loFormObject = _screen.Forms[lnI]
  lcErrText = lcErrText + loFormObject.Class + " " + loFormObject.Name + " " + ;
      IIF(TYPE("loFormObject.FormMode") = "C", loFormObject.FormMode, "") + " " + ;
      IIF(TYPE("loFormObject.ActiveControl.Name") = "C", loFormObject.ActiveControl.Name, "") + CHR(13)+CHR(10)
NEXT


lcErrText = lcErrText + CHR(13)+CHR(10) + "Workarea list:" + CHR(13)+CHR(10)

lnWAcount = AUSED(laUsed)
FOR lnI = 1 TO m.lnWAcount
  lcErrText = lcErrText + STR(laUsed[lnI, 2], 5) + " " + PADR(laUsed[lnI, 1], 40) + ;
     TRANSFORM(RECNO(laUsed[lnI, 2])) + '/' + TRANSFORM(RECCOUNT(laUsed[lnI, 2])) + " " + ;
     TRANSFORM(BOF(laUsed[lnI, 2])) + " " + TRANSFORM(EOF(laUsed[lnI, 2])) + CHR(13)+CHR(10)
NEXT

RELEASE laUsed

= STRTOFILE(lcErrText, lcOutFile)

LOCAL ARRAY laCallStack[1]
= ASTACKINFO(laCallStack)

LIST STATUS TO FILE (lcOutFile) ADDITIVE NOCONSOLE
LIST MEMORY TO FILE (lcOutFile) ADDITIVE NOCONSOLE
LIST OBJECTS TO FILE (lcOutFile) ADDITIVE NOCONSOLE

LOCAL lnErrId, loErrRec

*-- Save error info into a table if possible
IF VARTYPE(gc_site_code) = 'C' AND !EMPTY(m.gc_site_code)
  TRY
    IF USED("ERRORLOG") OR OpenTable("ERRORLOG", .F., .T., "ERRORLOG")
      IF USED("COUNTERS") OR OpenTable("COUNTERS", .F., .T., "COUNTERS")
        lnErrId = CreateNewPK("ERRORLOGID")
        USE IN SELECT("COUNTERS")
        IF m.lnErrId > 0
          SELECT ERRORLOG
          SCATTER MEMO NAME loErrRec BLANK
          loErrRec.Id = m.lnErrId
          loErrRec.LogInfo = FILETOSTR(lcOutFile)
          UpdateSystemColumns(loErrRec, .T.)
          IF FLOCK()
            INSERT INTO ERRORLOG FROM NAME loErrRec
          ENDIF
        ENDIF
      ENDIF
      USE IN SELECT("ERRORLOG")
    ENDIF
  CATCH
    USE IN SELECT("COUNTERS")
    USE IN SELECT("ERRORLOG")
  ENDTRY
  
  SELECT (lnWarea)
  
ENDIF

WAIT WINDOW "ERROR INFORMATION WAS RECORDED IN " + lcOutFile TIMEOUT 1

IF m.gn_errCount > 20
  ON ERROR CANCEL
  CLEAR EVENTS
  IF VERSION(2) = 0
    QUIT
  ELSE
    SUSPEND
  ENDIF
ENDIF

Open in new window

Disadvantage of this error procedure could be an automatic program continuation after the error occurence. It can cause unpredictable results sometimes but it ignores minor errors which do not affect program run in most of the cases. You may add some dialog to PrgError to let users decide if they want to continue or not. I am testing gn_errCount in regular code which allows to make this decision automatically.

I am using TRY - CATCH for "local error handling" but to use this structure as the global error handler should also be possible.

ON ERROR setting cannot be ignored in your code, so if an error occurs it must pass the program flow into the error routine.
0
 
LVL 29

Expert Comment

by:Olaf Doschke
ID: 36497138
Try RETURN or RETRY from within a Catch Block. It's not supported.

With these last lines of your error handler, you can debug when an error occurred and return to the line of error:

If _vfp.startmode=0
   set step on
   return
Endif

This is not possible from CATCH, so TRY .. CATCH is bad for global error handling alone because of that.

Bye, Olaf.
0
 

Author Closing Comment

by:luciliacoelho
ID: 36520316
In fact when I tried to use directly the error message and send to the screen through a MessageBox, directly. The MyErrorHandling routine didn't work at all. The workaround I used was the following: The data gathered from an error is firstly writen in a errorlog table then I use this data to interact with the user.
0
 
LVL 27

Expert Comment

by:CaptainCyril
ID: 36520758
It seems that the variables you were using are local to a certain procedure/function. It's best errors are logged in a database or text file. I also send them by email to the development team of course with the permission of the user.
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Microsoft Visual FoxPro (short VFP) is a programming language with it’s own IDE and database, ranking somewhat between Access and VB.NET + SQL Server (Express). Product Description: http://msdn.microsoft.com/en-us/vfoxpro/default.aspx (http://msd…
The business world is becoming increasingly integrated with tech. It’s not just for a select few anymore — but what about if you have a small business? It may be easier than you think to integrate technology into your small business, and it’s likely…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question