Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Bug in RETURN TO ... (revisited)
Message
 
To
04/02/2009 15:08:46
General information
Forum:
Visual FoxPro
Category:
Troubleshooting
Environment versions
Visual FoxPro:
VFP 6 SP5
OS:
Windows XP SP2
Miscellaneous
Thread ID:
01378918
Message ID:
01379385
Views:
22
>>Sergey (and Agnes),
>>
>>I posted this sample program in the hope that someone can solve a problem that is of some importance to VFP error handling in general. I regret my choice of words, since any argument about labeling this as a "bug" or a "documentation error" or an "undocumented feature" is beside the point. Suffice it to say that there is an anomaly, and I will try to clarify its practical significance. The test program I provided makes it easy to confirm examples of the anomaly. My hope is that you or someone else might be clever enough to devise a workaround that makes it possible to consistently return a value of .F. via the RETURN TO ... statement.
>>
>>The RETURN TO ... statement is useful in the context of an error handler, as a way of preventing the execution of subsequent lines of code within the same procedure that triggered the error. I'm sure you are familiar with the undesirable situation where an unanticipated error leads to a cascade of further errors, which are of no interest to the user, but are simply due to a normal RETURN from the error handler. Using RETURN TO MASTER or RETURN TO whatever program level contains the READ EVENTS, one can avoid these undesirable secondary errors, and the return value that results from the RETURN TO ... statement is of no importance in such cases.
>>
>>More generally, though, it may not be ideal to return directly from an error handler all the way to the READ EVENTS level. The least disruptive return from an error handler that avoids continuing in the procedure that triggered the error would be to return directly to the calling program. As often as not, programs are called as functions, and it is a common convention that functions return .F. to indicate failure. For that reason, it is more useful for such a "catch-all" error handler to return .F. when it pops the stack as described. This allows the immediate caller of the offending program to recognize the error and deal with it in its usual manner, without the necessity of having any additional error checking logic. To the caller, it frequently is immaterial why or how a function has failed - the caller simply needs to recognize that the function failed, so it can perform its usual cleanups. By using this type of approach to error handling in the general case of exceptional/abnormal/unanticipated errors, complex applications can be made more robust, with a minimum of explicit error handling logic. Instead of totally collapsing upon encountering the slightest unexpected error, applications can deal with errors more gracefully. Without scads of extra error-checking logic and defensive coding, this allows applications to do a better job of thoroughly detecting and reporting errors.
>>
>>I hope my explanation clarifies why seemingly obscure anomalies in an undocumented feature of the seldom-used RETURN TO ... statement actually are of some general importance. My expectation is that this problem applies to all versions of VFP, and I invite anyone to test and confirm this. More importantly, the question is whether anyone can find a solution: how to make the RETURN TO ... statement consistently return .F.?
>
>Hmm, I look on RETURN ... TO as a GOTO and I'm philosophically opposed to its use. At the very least, it's a break of encapsulation and encourages dependencies and spaghetti code.
>
>Correct me if I'm wrong, but it seems to me you're most concerned with showing users a cascade of techy errors. An approach I've used is to create a logical global object property (or variable) such as DisplayErrorsToUser, which simply controls whether error message(s) at a given procedure level are displayed. You could probably achieve finer control with a global Error array, object or some other type of stack structure that dynamically matches your call stack; you could have multiple error attributes per procedure such as Message, DisplayMessageToUser, etc.
>
>When writing high-reliability code, I've found I always want to log all errors at all procedure levels, often with associated LIST MEMORY, LIST STATUS dumps etc. but I fully agree the user doesn't want to see most, if any, of it.
>
>If you're able to upgrade, later versions of VFP offer TRY...CATCH with other possibilities for error handling.

Hi Al,

I agree with your philosophical opposition to the use of RETURN TO ... in general, with the exception of one important case, which is by definition an extraordinary one. That exception is the case of returning from an error handler when the error was completely unanticipated, i.e. the default, "catch-all" error handler of last resort. This has to do with the final action that any such error handler can take, regardless of the type of error handling mechanism used, be it ON ERROR, Error event, or TRY...CATCH.

You seem to have misunderstood my previous reply. I certainly do not wish to show a "cascade of techy errors" - just the opposite! I do not want spurious, secondary errors to occur at all, and this is precisely why I need the RETURN TO ... command. If the error handler were to do a normal RETURN, it would resume at the next line of the procedure where a completely unexpected error just occurred. Had the possibility of an error been expected, the next line would include some suitable failure check. But I just said that the errors I'm concerned with are those that were entirely unforeseen, so the next line of code to which a normal Error RETURN would proceed is not such a failure test. The next line will be some random step that naively assumes the preceding step succeeded, and this would likely trigger another error, and then another, and so on, until the procedure finally limps its way along to a return statement. Hopefully, when the offending procedure finally arrives at its own return statement, it won't blindly return a spurious success indicator, but in fact that is quite possible, since, after all, this procedure did not expect this error!

Wouldn't it be nice if, in such cases of unanticipated errors, the error handler could avoid the whole mess simply by returning a failure indicator directly to the caller of the function that encountered this error. That simple action would assure that no spurious, secondary errors are generated in the function that got caught with its pants down, and it would also provide a more reliable indication to the caller about this function's embarassing failure. My error handler does this by using RETURN TO ... and passing a return value equal to .F., which works 99% of the time. It took me quite a while to identify more than one case where this technique doesn't work, apparently due to a VFP bug, or whatever you wish to call it.

I've tried to explain this is in the most general terms, so that people can see that it is a basic issue that could apply to any of a variety of error handling frameworks. The bottom line is that the ability to RETURN TO an intermediate stack level with a .F. result is indeed useful, if not indispensable in the implementation of VFP error handling. Do I sound like a beginner? If I haven't made the argument clearly enough, humor me and consider this a challenging little puzzle. I've supplied a program that anyone can test simply by pasting it into bug2b2.prg and running the command: ? bug2b2("any non-existing filename.txt"). Can you solve this puzzle?

Mike
Montage

"Free at last..."
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform