Error Handler Priority
Visual FoxPro provides several error handlers you can use to detect and handle errors in code.
Warning
The use of TRY...CATCH statements in a method whose class definition does not have Error event or method code might impact existing code and possibly break backward compatibility. Therefore, TRY...CATCH statements in methods should call only other object methods that contain Error event or method code.
The following table summarizes the priority of error handlers.
When only the following error handler exists | Error handler priority |
---|---|
None or no existing error handlers can handle the error |
Visual FoxPro system error message |
ON ERROR command |
ON ERROR takes precedence until another ON ERROR is called or the Visual FoxPro error message system is restored. Otherwise, Visual FoxPro displays a system error message. |
TRY...CATCH...FINALLY command |
TRY...CATCH...FINALLY takes precedence when an error occurs in TRY block. Otherwise, Visual FoxPro displays a system error message. |
Error event or method |
Error takes precedence when an error occurs in an object's method code. Otherwise, Visual FoxPro displays a system error message. |
TRY...CATCH...FINALLY command ON ERROR command |
TRY...CATCH...FINALLY takes precedence when an error occurs in a TRY block. ON ERROR takes precedence when:
Otherwise, Visual FoxPro displays a system error message. |
Error event or methodON ERROR command |
Error takes precedence when an error occurs in object method code. ON ERROR takes precedence when:
Otherwise, Visual FoxPro displays a system error message. |
TRY...CATCH...FINALLY commandError event or method |
TRY...CATCH...FINALLY takes precedence when:
Error takes precedence when:
Otherwise, Visual FoxPro displays a system error message. |
Summary of Error Handling in Object Method Code
For errors that occur in an object's method code, the order of priority for error handlers is summarized as follows:
Immediate TRY...CATCH, if it exists, in the same method that the error occurs. This applies also to external procedures that a method calls.
Error event, if it exists, for the object.
TRY...CATCH at the next level up in the calling chain or in a higher-level method.
ON ERROR routine, if it exists.
Visual FoxPro system error message.
For more information error handling priority within TRY...CATCH...FINALLY structures, see Error Handling Priority in TRY...CATCH...FINALLY Structures. For more information about error handling priority in classes and objects, see Error Handling Priority in Classes and Objects.
Error Handling Priority in TRY...CATCH...FINALLY Structures
The following table summarizes the sequence of actions when handling errors or THROW commands in the TRY block of a TRY...CATCH...FINALLY structure.
When the following error handlers exist and an error occurs in the first code block as listed | Sequence of actions |
---|---|
None |
Display appropriate Visual FoxPro system error message. |
CATCH code block |
CATCH code block handles the error. |
CATCH code blockFINALLY code block |
CATCH code block handles the error.FINALLY code block runs. |
Inner CATCH code block Inner FINALLY code block Outer TRY structure |
Inner CATCH code block handles the error. Inner FINALLY code block runs. Outer FINALLY code block runs. If no inner CATCH code block exists, inner FINALLY code block runs, outer CATCH code block handles the error, and outer FINALLY code block runs. |
CATCH code block FINALLY code block ON ERROR command |
CATCH code block handles the error. FINALLY code block runs.ON ERROR command runs. If no CATCH code block exists, FINALLY code block runs, and ON ERROR handles the error. |
CATCH code block FINALLY code block Error code block |
CATCH code block handles the error. FINALLY code block runs.Error event runs. If no CATCH code block exists, FINALLY code block runs, and Error event handles the error. |
For information about how TRY...CATCH...FINALLY structures handle errors, see Structured Error Handling.
Error Handling Priority in Classes and Objects
When an error occurs in an object's method code, and the method is called directly or from the TRY block of a TRY...CATCH...FINALLY structure, Visual FoxPro follows the error handling procedure for that particular object. This protocol makes it possible for you to maintain encapsulation and control of your components. Typically, the object's Error event, if it exists, takes precedence over other error handlers unless the object's method code contains its own TRY...CATCH...FINALLY structure.
For more information about error handling for classes and objects, see Class and Object Error Handling.
Examples of Error Handling Priority for Object Method Code
In the following example where the class contains an Error event, the code instantiates an object from a custom class named MyObjectClass, which defines two methods that contain TRY...CATCH blocks, one method that contains an error, and an Error event. The object then calls two of the defined methods.
The TRY block in Method1 contains a call to the custom RaiseError method, which generates an error. However, the CATCH block in Method1 does not handle this error; instead, the code in the Error event for the class handles this error and displays the message specified. If the Error event did not exist, the CATCH block in Method1 would display the specified message.
In contrast, when an error occurs preceding the TRY block in Method2, the Error event handles this error by displaying the specified message. When a second error occurs in the TRY block in Method2, the CATCH block handles the second error and displays the specified message.
CLEAR
oMyObject = CREATEOBJECT("MyClass")
oMyObject.Method1()
?
oMyObject.Method2()
DEFINE CLASS MyClass AS Custom
PROCEDURE Method1
? "Method1"
TRY
? "Calling RaiseError method in TRY block for Method1."
This.RaiseError()
CATCH
? "Entered CATCH block for Method1. Caught error."
ENDTRY
ENDPROC
PROCEDURE Method2
? "Method2"
? "Generating an error before TRY block in Method2."
ERROR 1
TRY
? "Generating an error in TRY block for Method2."
ERROR 1
CATCH
? "Entered CATCH block for Method2. Caught error."
ENDTRY
ENDPROC
PROCEDURE RaiseError
? "Entered RaiseError method. Generating an error."
ERROR 1
ENDPROC
PROCEDURE Error(t1,t2,t3)
? "Error event for MyObjectClass occurred."
ENDPROC
ENDDEFINE
In the following example where the class does not contain an Error event, the code instantiates an object from a custom class named MyClass, which defines two methods: the first contains a TRY...CATCH block while the second does not.
The TRY block in myMethod1 contains a call to myMethod2, which generates an error. The CATCH block in Method1 handles this error and displays information for the Visual FoxPro error generated.
However, if the example called myMethod2 directly, for example, by following oMyObject.myMethod1()
with oMyObject.myMethod2()
, then the ON ERROR
DO errorHandler
statement would need to specify a functional routine named errorHandler to handle the error in myMethod2. After handling the error, the ON ERROR routine returns execution to the program so that the statement following the one containing the error can execute.
CLEAR
ON ERROR DO errorHandler && Create a functional error handler to test.
oMyObject=CREATEOBJECT("myClass")
oMyObject.myMethod1()
* oMyObject.myMethod2() && Remove comment character to test this line.
DEFINE CLASS myClass AS Custom
PROCEDURE myMethod1
? "myMethod1"
TRY
? "Calling myMethod2 in TRY block for myMethod1."
THIS.myMethod2()
CATCH TO omyError
? "Entered CATCH block for myMethod1. Caught: ", ;
omyError.ErrorNo, " ", omyError.Message
ENDTRY
ENDPROC
PROCEDURE myMethod2
?
? "myMethod2"
? "Generating an error in myMethod2."
x=y && Variable y does not exist. CATCH handles this error.
? "This line displays if CATCH does not handle the preceding error."
ENDPROC
ENDDEFINE