Rick Strahl's Weblog
Rick Strahl's FoxPro and Web Connection Weblog
White Papers | Products | Message Board | News |

ExecScript and Error Handling


2 comments
August 22, 2006 •

ExecScript is one of the more powerful commands in the FoxPro language. It allows execution of an arbitrary block of code by simply passing a string to the function. Very powerful, very dangerous and pretty cool if used in the right places.

 

Unfortunately ExecScript has one major shortcoming: Error handling. I’ve been working on a consistent scripting implementation that can deal with executing ASP style script pages consistently in the Web Connection framework and in FoxPro in general. The idea is that you can take an arbitrary template file and execute it as FoxPro code.

 

In any case one of the mechanism that the scripting framework uses is ExecScript to allow for completely dynamic compilation that requires no files on disk and nothing that stays loaded in memory (one of the shortcomings of generating and executing a PRG file on your own – there can be issues having multiple VFP instances seeing changes to script files).

 

So ExecScript works graeat for this – you can pass a string to it and it will execute the code and return a result if you RETURN a value. But what’s not so nice is the error handling. If ExecScript fails it throws an error, which is fine. Unfortunately the error behavior is mixed.

 

Script Compilation Error

If there’s a compilation VFP throws a generic Syntax Error (error 10) and provides no further indication of what’s wrong.

 

Runtime Execution Error in Script Code

In this case VFP will throw a meaningful error that can be captured in a TRY/CATCH block. The Exception’s LineNo and ErrorDetail return appropriate values for the error. So here’s a wrapper function that can deal with ExecScript more gracefully:

 

 

*************************************************************

DEFINE CLASS wwEval AS RELATION

*************************************************************

***    Author: Rick Strahl

***            (c) West Wind Technologies, 1996

***   Contact: (541) 386-2087  / rstrahl@west-wind.com

***  Modified: 08/21/2006

***  Function: Evaluation Class used to safely execute

***            evaluation strings and test for error

*************************************************************

 

*** Custom Properties

lError=.F.

nError=0

 

cResultType="L"

vErrorResult=.F.

Result=""

 

*** These properties are specific to executing

nErrorLine=0

cErrorCode=""

cErrorMessage=""

 

 

************************************************************************

* wwEval :: Execute

*********************************

***  Function:

***    Assume: Codeblock Class must be loade with

***            SET PROCEDURE TO CodeBlckClass

***      Pass: lcCode   -   Any block of Visual FoxPro code.

***    Return: Result of the code

************************************************************************

FUNCTION Execute

LPARAMETERS lcCode

 

this.lError = .F.

 

LOCAL loException, loPassedException as Exception

*** Execute with ExecScript

loException = null

TRY

      this.Result = EXECSCRIPT( lcCode ) 

CATCH TO loException

      this.lError = .t.

    IF loException.ErrorNo = 10

          THIS.cErrorMessage =  "Compilation Error: Syntax error in code"

          loException.LineContents = ""

          loException.LineNo = 0

    ELSE

          THIS.cErrorMessage = loException.Message

      ENDIF

 

   THIS.nError=loException.ErrorNo

   THIS.nErrorLine=loException.LineNo

   THIS.cErrorCode=loException.LineContents

ENDTRY  

 

IF this.lError

   RETURN THIS.vErrorResult

ENDIF

  

RETURN THIS.Result

* Execute

 

ENDDEFINE

 

The code handles a couple of wrapping issues that I think are pretty important to effectively executing dynamic code. First there’s the obvious exception handling. You don’t want to do this sort of checking in your application code but rather execute the code and check for success:

 

loEval = CREATEOBJECT("wwEval")

loEval.vErrorResult = ""

 

TEXT TO lcCode NOSHOW

lcOutput = ""

FOR x = 1 TO 10

   lcOutput = lcOUtput + TRANSFORM(x) + CHR(13)

ENDFOR

RETURN lcOutput

ENDTEXT

 

lcResult = loEval.Execute(lcCode)

 

IF loEval.lError

   ? loEval.cErrorMessage

   RETURN

ENDIF

 

? lcResult

This is a lot cleaner than  having to wrap the code in exceptions on your application code.

 

The code also deals with the insurmountable Compilation Error problem by at least returning a manageable error message. I sure wish Microsoft would have gone the extra step and provided us with the compiler error. Surely the compiler knows where the code fails – alas I suspect there could be more than one error and returning this info would be inconsistent, but still anything better than a generic error would have been nice.

 

And just in case you’re thinking AERROR() is any better – it’s not providing any additional info either <g>.

 

So ExecScript works well for certain scenarios. Which ones? The two main scenarios are:

 

  • When you absolutely need dynamic compilation
  • You need to execute code from a string and can’t use PRG files

 

Remember that ExecScript behind the scenes generates a PRG file, compiles it, executes and then releases the files and deletes them. There’s a lot of work happening there, so be somewhat wary of ExecScript in terms of performance.

 

Starting with VFP 8 Visual FoxPro has the ability to compile PRG files at runtime, so it is possible to generate, compile and run PRG files on your own. The advantage there is that you can leave the PRG/FXP file sticking around and you can reuse it which is much faster than letting VFP go through the whole Generation/compilation/run/cleanup cycle that goes on with ExecScript.

 

I’ll post more about this manual approach as well as the wwScripting class in a few days.

Posted in:

Feedback for this Weblog Entry


Re: ExecScript and Error Handling



Frederick Hodges
January 25, 2007

I'm having trouble fixing the Runtime Error/Syntax Error Pop-up. If you could please inform me how to remove it, step-by-step, I would greatly appreciate it. If you need anymore information, please let me know. Journ418@aol.com

Re: ExecScript and Error Handling



Rick Strahl
January 29, 2007

It's in the article. Try/Catch is your friend...

 
© Rick Strahl, West Wind Technologies, 2003 - 2024