Solved

on error handling Visual Foxpro

Posted on 2011-09-06
7
1,062 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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 41

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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

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…
Short answer to this question: there is no effective WiFi manager in iOS devices as seen in Windows WiFi or Macbook OSx WiFi management, but this article will try and provide some amicable solutions to better suite your needs.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now