function bug2b2 * By M. Asherman, 2/2/09 * * I posted a similar version of this test program to UT Thread 620507 on 2/15/2002. * (Also see related thread UT Thread 620089 of 2/14/2002.) * * This program demonstrates an apparent bug in VFP6 SP5, which may also apply to later versions. * In some cases, using RETURN TO ... to return a result from an Error event yields the wrong value. * For example, this program demonstrates such erroneous results for some * "File does not exist" or "Variable not found" errors. * This bug makes it difficult to handle unexpected errors cleanly. * * To see the problem, copy this program to a file named bug2b2.prg, and run it from VFP * with a command line such as this: ? bug2b2("any old file.txt"). * Compare the outcomes for the 3 sample actions in PROCEDURE openpath. * Each of those actions triggers an "unexpected" error, but only one of those cases * is handled correctly. The mis-handled cases lead to an additional error, because * the return value from the Error event is not the expected Logical value (.F.). * The erroneous Error return value (produced by the RETURN TO ... statement) * is the character string argument that was passed to the method in which the error occurred, * instead of being .F., as it always should be. lparameters filenm_arg * filenm_arg: path spec. of initial file to open and display in this control. * Path may be relative or absolute. * cleanup from prior test, if necessary if vartype(_screen.bug2) = 'O' _screen.removeobject('bug2') && discard previous _screen.bug2 object endif * launch editbox with given file's contents as member _screen.bug2 _screen.newobject('bug2', 'bug2editbox', '', '', m.filenm_arg) if vartype(_screen.bug2) = 'O' _screen.bug2.visible = .t. && make editbox with file contents visible return .t. && success endif return .f. && failure DEFINE CLASS bug2editbox AS editbox Height = 172 Width = 336 Name = "bug2editbox" PROCEDURE openpath * takes 1 optional arg. lparameters filenm_arg * peform file opening logic (compare behavior of each of the following 3 lines) this.value = filetostr(m.filenm_arg) && if file does not exist -> flaky error handling! * this.value = hahah() && file does not exist error is handled correctly in this case * this.value = xyz && variable not found -> flaky error handling for this case, too! return .t. && success (we don't want to execute this line if preceding step failed) ENDPROC PROCEDURE Init lparameters filenm_arg && takes 1 optional argument local success success = .t. if not empty(m.filenm_arg) && file name was supplied success = this.openpath(m.filenm_arg) && this method handles control-specific logic * display diagnostic info, demonstrating flaky return from error cases wait window 'vartype(m.success) = ' + vartype(m.success) ; + chr(13) + "Success = " + transform(m.success) if not m.success && this test will bomb if value is not Logical return .f. && fail - prevent instantiation endif endif return m.success && success - allow this object to be created ENDPROC PROCEDURE Error LPARAMETERS nError, cMethod, nLine local retval retval = .f. * display details about the error that was triggered messagebox("Error # " + ltrim(str(m.nerror)) ; + ", method = " + m.cMethod ; + ", line # " + ltrim(str(m.nLine)) ; + chr(13) + "Message() = " + Message() ; + chr(13) + "Message(1) = " + Message(1) ; + chr(13) + "SYS(2018) = " + SYS(2018)) * use RETURN TO ... to avoid allowing the method that encountered error to continue return to init m.retval && this produces flaky result after some types of errors * return m.retval && this would return to openpath, despite unexpected error ENDPROC ENDDEFINE