Try OpenEdge Now
skip to main content
ABL Essentials
Managing Transactions : Using the UNDO statement : Handling the ERROR condition : ERROR-STATUS system handle
 
ERROR-STATUS system handle
In most cases, you do not want raw error messages to be shown to users, even when it is their mistake that causes the error. Even more important, it is essential that your procedures anticipate all possible error conditions whether they are caused by a user action or not, and respond to them, in some cases by suppressing an error message altogether. In addition, your application must define a mechanism for returning errors generated in an AppServer session back to the client, because by default OpenEdge messages simply go to the server log file and are never seen.
To check for errors programmatically, you use the ERROR-STATUS system handle. Many ABL statements support the NO-ERROR option as the last keyword in the statement. If you specify this option, that statement does not generate the ERROR condition. Instead, if the statement cannot execute properly, execution continues with the next statement. You can then check whether an error occurred by examining the attributes of the ERROR-STATUS system handle.
The ERROR-STATUS handle contains information on the last statement executed with the NO-ERROR option. The logical attribute ERROR-STATUS:ERROR tells you whether an error occurred. Because in some cases a single error can return multiple messages, the NUM-MESSAGES attribute tells you how many messages there are. The GET-MESSAGE(<msg-num>) method returns the text of the message, and the GET-NUMBER(msg-num) method returns the internal message number. This is a simple example:
DEFINE VARIABLE iMsg AS INTEGER    NO-UNDO.
FIND Customer WHERE CustNum = 9876 NO-ERROR.
IF ERROR-STATUS:ERROR THEN
DO iMsg = 1 TO ERROR-STATUS:NUM-MESSAGES:
  MESSAGE "Error number: " ERROR-STATUS:GET-NUMBER(iMsg) SKIP
    ERROR-STATUS:GET-MESSAGE(iMsg)
    VIEW-AS ALERT-BOX ERROR.
END.
Because there is no Customer 9876, you get an error and your code displays the message box shown in the following figure.
Figure 59. Example error message
Because you are intercepting the error, you can handle it more gracefully than this and also have your program logic proceed accordingly. You can check the message number using the GET-NUMBER method and put code in your application to deal with each of the possible error conditions.
Remember also that ABL provides special built-in functions, such as AVAILABLE and LOCKED, to make it easier for you to tell when certain common errors have occurred:
FIND Customer WHERE CustNum = 9876 NO-ERROR.
IF NOT AVAILABLE Customer THEN
  MESSAGE "So sorry, but this Customer does not seem to be there."
    VIEW-AS ALERT-BOX INFORMATION.
The following figure shows the result.
Figure 60. Example information message
Note that the ERROR-STATUS handle holds only error conditions and messages for the most recently executed statement with the NO-ERROR option. It does not accumulate errors over multiple statements. The ERROR-STATUS remains in effect (and checkable by your code) until the next statement with the NO-ERROR option.
When the ERROR condition occurs anywhere outside of a trigger block, the AVM looks for the closest block with the error property and undoes and retries that block. As discussed earlier, if it is not meaningful to retry the block. the AVM proceeds to the next iteration if it is a repeating block or else leaves the block.
Because this is the default, the following transaction header from the sample saveOrder procedure could simply be DO TRANSACTION: and have the same effect:
DO TRANSACTION ON ERROR UNDO, LEAVE: