Randy Pearson, Cycla Corporation, December 27, 2002 [Updated October 18, 2006]
Below is a matrix that provides a reference for VFPs error handling strategies. The columns depict each of eight different error triggering event types, while the rows signify the most immediate type of error handling that is in effect higher in the calling chain. There is also a sample program at the bottom of the page that you can cut and paste into VFP to try out these combinations. Simply call the program passing a numeric parameter with the Case number as shown in the matrix.
|
Immediate |
Call from an Outer TRY/CATCH(c) (g) | Call from Object with Error() Method(d) (g) | Call with an ON ERROR Routine in Effect | No Other Error Handling |
| Triggering Event | ||||
| TRY block runs without error [Case 0] | Any code in FINALLY block is executed(a), and then processing continues with code after ENDTRY. | |||
| TRY exception handled by a CATCH (no THROW) [Case 1] | Remainder of TRY block is aborted. Code in applicable CATCH block is run. Any code in FINALLY block is then executed(a), after which processing continues with code after ENDTRY. | |||
| Including a THROW in the CATCH block [Case 2] | FINALLY code is run, but code after ENDTRY is not
run. Error 2071 is potentially caught and handled by outer block. Outer FINALLY block also executes. Note that you could re-THROW some exceptions even higher in the calling chain.(c) [Case 12] |
Any code in FINALLY block is executed first(!)(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by Error() method of calling object. MESSAGE() contains parsed info on thrown exception, which generated Error 2071, "User Thrown Error."(g) [Case 102] | Any code in FINALLY block is executed first(!)(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by ON ERROR routine. MESSAGE() contains parsed info on thrown exception, which generated Error 2071, "User Thrown Error."(g) [Case 1002] | Any code in FINALLY block is executed first(!)(a) and then Error 2059, "Unhandled Structured Exception," is generated, caught by VFP which shows the usual message box with parsed info on thrown exception, which generated Error 2071, "User Thrown Error."(g) [Case 2] |
| TRY exception not handled [Case 3] | First the FINALLY block is executed, and then
the outer CATCH (and then outer FINALLY, etc.) block is executed.(c) [Case 13] Important: The error that is "caught" by the outer block is the original error (vs. Error 2059), as this is proper exception handling. |
Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by Error() method of calling object. MESSAGE() contains parsed info on original exception, but you cannot get at true original exception object. [Case 103] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by ON ERROR routine. MESSAGE() contains parsed info on original exception, but you cannot get at true original exception object. (e) [Case 1003] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and caught by VFP, which shows a message box with parsed information on the original exception. [Case 3] |
| Second Error in CATCH code [Case 4] | First the FINALLY block is executed, and then the second error is caught by the outer block, so the outer CATCH (and then outer FINALLY, etc.) block is executed. The original error is completely masked by the second error.(c) [Cases 14 and 15] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by Error() method of calling object. MESSAGE() contains parsed info on the second error. The original error is completely masked by the second error. [Cases 104 and 105] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by ON ERROR routine. MESSAGE() contains parsed info on the second error. The original error is completely masked by the second error. [Cases 1004 and 1005] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and caught by VFP, which shows a message box with parsed information on the second error. The original error is completely masked by the second error. [Cases 4 and 5] |
| Second Error in FINALLY code [Case 5] | ||||
| Error in FINALLY code (no original error)(f) [Case 6] | First the FINALLY block is executed, and then
the error is caught by the outer block.(c) [Case 16] Important: The error that is "caught" by the outer block is the original error (vs. Error 2059), as this is technically proper exception handling. Note: There is no difference, as seen by the outer block, between unhandled errors in TRY code and errors in FINALLY code of the inner block. |
Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by Error() method of calling object. MESSAGE() contains parsed info on original exception, but you cannot get at true original exception object. [Case 106] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and trapped by ON ERROR routine. MESSAGE() contains parsed info on original exception, but you cannot get at true original exception object. (e) [Case 1006] | Any code in FINALLY block is executed(a) and then Error 2059, "Unhandled Structured Exception," is generated and caught by VFP, which shows a message box with parsed information on the original exception. [Case 6] |
| Error outside TRY block [Case 7] | Error properly handled by outer TRY block. [Case 17] | Error properly handled by Error() method of calling object. [Case 107] | Error properly handled by ON ERROR routine. [Case 1007] | Error properly handled by VFP. [Case 7] |
| Error in called COM object. | Depends on whether COMRETURNERROR is used in called object. See discussion by Donnael Consulting at http://www.donnael.com/tips.htm#CRETest. | |||
|
RETURN TO MASTER RETURN TO SomeModule |
If the RETURN TO point is higher in the call stack than an intervening TRY/CATCH block, then VFP error 2060 is triggered. In VFP 8, error 2060 was not trappable, which would result in a VFP error dialog--a killer for server-based apps. Starting with VFP 9, error 2060 is trappable, so if you design carefully, it may be possible to cope; nevertheless, you still cannot RETURN TO through an intermediate TRY/CATCH. | No unexpected effect. | ||
Footnotes
Implications
Practice Code (refer to Case numbers in matrix above)
Simply call the program passing a numeric parameter with the Case number as shown in the matrix.