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:

  • An error occurs outside the TRY block.

  • An error occurs in the CATCH block.

  • An error occurs in the FINALLY block.

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:

  • An error occurs outside a class definition.

  • An error occurs inside a class definition but outside method code. The error is detected at the point of instantiating the object.

Otherwise, Visual FoxPro displays a system error message.

TRY...CATCH...FINALLY commandError event or method

TRY...CATCH...FINALLY takes precedence when:

  • An error occurs in a TRY block outside a class definition.

  • An error occurs inside an object's method code and is within a TRY block.

  • An error originates in a class definition outside method code but occurs in a TRY block outside the class definition.

  • An error occurs in a TRY block inside external procedure or object method code, and the method or procedure is called directly or from another method, regardless of whether the method call appears inside or outside a TRY block.

Error takes precedence when:

  • An error occurs inside method code but outside a TRY block.

  • An error occurs in an object's method code, and the method is called directly or is called from another method, regardless of whether the method call appears inside or outside a TRY block.

    Note

    If the method call is in a TRY block, and no immediate Error event or method code exists for the object, Visual FoxPro searches for Error code inherited from the parent class or another class up the class hierarchy. If no Error code exists in the class hierarchy, Visual FoxPro looks for a CATCH block corresponding to the TRY block from which the method was called.

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

See Also

Concepts

Handling Run-Time Errors

Other Resources

Testing and Debugging Applications