ON

Purpose

Identifies the action to be taken when a particular condition is raised during execution of a program.

Syntax

ON condition-name ON-unit;

or

ON condition-name SYSTEM;

Parameters

condition-name
ANYCONDITION, AREA, ATTENTION, CONDITION(name), CONVERSION, ENDFILE(f), ENDPAGE(f), ERROR, FINISH, FIXEDOVERFLOW, KEY(f), RECORD(f), OVERFLOW, SIZE, UNDEFINEDFILE(f), USERCONDITION (expression), USERCONDITION(SS$_UNWIND), VAXCONDITION (expression), or ZERODIVIDE.
ON-unit
A BEGIN block or a statement other than PROCEDURE, DO, END, DECLARE, FORMAT, or RETURN, which may include the CALL RESIGNAL statement.
Note:

Abbreviation(s):

  • ATTN for ATTENTION
  • COND for CONDITION
  • CONV for CONVERSION
  • OFL for OVERFLOW
  • UNDF for UNDEFINEDFILE
  • ZDIV for ZERODIVIDE

Description

The ON statement identifies the action to be taken when a particular condition is signaled during execution of a program.

The ON statement is executable and must be executed before the statement that signals the specified condition.

Execution of the ON statement establishes the ON-unit as if it were a procedure that is to be called when the condition is signaled. It does not execute the ON-unit.

If an ON-unit for this condition has already been established in the current block activation, it is replaced by this ON-unit.

During its execution, an ON-unit can do any of the following:

  • Handle the condition, then return control to the point at which the condition was signaled.
  • Resignal the condition and ask Open PL/I to find another ON-unit to handle the condition.
  • Execute a nonlocal GOTO statement, which causes Open PL/I to unwind the call stack.
  • End the program.

You can receive a notification when the run time or debugger has detected a condition that triggers an ON-unit, allowing you to investigate the state of a program and optionally set breakpoints. See Checking Program State with ON-unit Notification for more information.

An ON-unit remains established until it is replaced by another, until it is reverted by a REVERT statement, or until the block activation in which it was established is ended.

When a condition is signaled, each block activation, beginning with the current block activation, is examined to see if it has an established ON-unit for the condition. If it does not, the previous block activation is examined until an ON-unit for the condition is found. If no ON-unit exists, a default ON-unit is invoked. The default ON-unit for ENDFILE signals the ERROR condition. The default ON-unit for ENDPAGE puts a new page; that is, it is equivalent to executing a PUT PAGE statement. The default ON-unit for FINISH returns control to the point in the program following the location where the signal occurred. The default ON-unit for all the other conditions signal the ERROR condition which, if not handled by an ON-unit for ERROR, causes an error diagnostic to display and then halts the program.

The consequence of this mechanism is that a block may establish its own ON-unit for a condition or may choose to let its caller's ON-unit handle the condition. Any ON-unit established by a block is reverted to when the block returns to its caller or is otherwise terminated.

A signal causes an ON-unit to be called just as if it were a procedure that had no parameters. The block activation resulting from this call is terminated when the ON-unit executes a GOTO or executes its END statement. In the latter case, control returns to the source of the signal.

A GOTO executed within an ON-unit and transferring control out of the ON-unit terminates the block activation of the ON-unit and any block activations back to, but not including, the activation of the block to which control is transferred.

The ON-conditions ENDFILE, ENDPAGE, KEY, and UNDEFINEDFILE are uniquely established for each file control block and are always written with a reference f that must identify a file value. The condition so referenced is effectively qualified by the file control block associated with f. Thus, ENDFILE(g) and ENDFILE(h) are different conditions if g and h identify different file control blocks, but they are the same condition if g and h identify the same file control block.

Just before these conditions are signaled, the value of the ONFILE built-in function is set to the file ID of the file control block for which the condition is being signaled. An ON-unit must not have a label prefix.

Unless otherwise specified, the default ON-units for the following conditions signal the ERROR condition which, if not caught, will print a message and end the execution of the program.

The SYSTEM keyword indicates that instead of executing the code in the ON-unit, a message describing the condition is printed and the ERROR condition is raised.

The ON condition SYSTEM statement can be useful when the user is trying to prevent an infinite loop in the exception handler when, for instance, an ERROR condition is raised in an ERROR ON-unit .

ON ERROR BEGIN;
        ON ERROR SYSTEM;
.
.
.
END;

If in the above example, the code following the ON ERROR SYSTEM statement causes an error exception, the program will be terminated after the message describing the error condition is printed.

The ON conditions are described as follows.

  • ANYCONDITION

    The ANYCONDITION ON-unit handles any signaled condition that cannot be handled by any other ON-unit. The ANYCONDITION ON-unit executes after every other ON-unit established in the block has been examined and found not to match the signaled condition.

  • AREA

    The AREA condition is raised when an attempt is made to allocate a based variable within an area that has too little free storage to accommodate it. The ON-unit for the AREA condition (for example, for a based area) can change the value of the pointer qualifying the area reference to point to a different area, where the allocation will be attempted again; or it can write out the area and reset it to empty.

    The AREA condition is also raised when an area assignment is attempted where the maximum size of the source area exceeds that of the target area.

  • ATTENTION

    The ATTENTION condition is raised when you signal attention at the terminal during program execution. This condition interrupts processing to enter an ATTENTION ON-unit.

    Upon return from an ATTENTION ON-unit, processing resumes at the point in the program immediately after the point at which the interrupt occurred.

  • CONDITION(name)

    The CONDITION condition is signaled by a SIGNAL statement that specifies the appropriate name. The name specified in the SIGNAL statement specifies which CONDITION condition is to be signaled. Note that the name specified in the CONDITION should be a condition name.

    This condition allows the user to establish an ON-unit that will be executed whenever a SIGNAL statement is executed specifying CONDITION and a name that matches the name in the ON statement.

    The following is an example of an ON CONDITION statement:

    ON CONDITION(OVERDRAFT) BEGIN; 
    
       PUT SKIP LIST('ACCOUNT HAD AN OVERDRAFT ON'||DATE())');
    
    END;
    .
    .
    .
    IF ACCOUNT_BALANCE < TOTAL WITHDRAWAL THEN SIGNAL CONDITION(OVERDRAFT);
  • CONVERSION

    The CONVERSION condition is signaled whenever an invalid conversion is attempted on character data. This attempt can be made during direct assignment of character data to numeric variable or during an input/output operation. For example, this condition can be raised when a character value that is being converted to a Fixed Binary value contains non-numeric characters, or if a character other than 0 or 1 is being converted to a bit data type.

    All conversions of character data are carried out character-by-character in a left-to-right sequence. The condition is raised for every invalid character.

    When an invalid character is encountered, the invalid character can be replaced within the ON-unit by using the ONSOURCE or ONCHAR pseudovariables.

    Upon return from a CONVERSION ON-unit, the program will retry the conversion if the ONSOURCE or ONCHAR pseudovariable has been used. If the error is not corrected, the ERROR condition is raised and control is passed back to the code that caused the exception to occur.

  • ENDFILE(f)

    The ENDFILE condition is signaled when an attempt is made to read past the end of a file. The end-of-file status of the file control block remains set so that subsequent reads also cause the signal to occur.

    Returning from the ON-unit transfers control to the statement following the GET or READ statement.

  • ENDPAGE(f)

    The ENDPAGE condition is signaled when the line to be written has a line number that is one greater than the page size or when a line number option that specifies a line number less then the current line number is issued for the STREAM OUTPUT PRINT file identified by f.

    If an ON-unit returns without writing a new page, the line number of the file increases indefinitely and the ENDPAGE condition is not signaled by subsequent output. However, if a new page is written by the ON-unit or at any time later, it resets the line number and allows ENDPAGE to be signaled the next time that the line number is one greater than the page size.

    Returning from the ON-unit returns to the point where the signal occurred and any additional output is then written to the stream.

    The default ON-unit puts a new page and returns.

  • ERROR

    The ERROR condition is signaled whenever the implementation detects an error. Just prior to signaling the condition, the value of the ONCODE built-in function is set to an implementation-defined integer value that serves as an error code that indicates which error occurred. (For more information, see your Open PL/I User's Guide.)

    Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.

    The default ON-unit writes an error message on an implementation-defined error file and executes a STOP statement. (For more information, see your Open PL/I User's Guide.)

    The following is an example of an ON ERROR statement.

    ON ERROR BEGIN;
       PUT SKIP LIST ('AN UNIDENTIFIED ERROR OCCURRED'); 
    END;
  • FINISH

    The FINISH condition handles the following conditions:

    • A STOP statement has been executed.
    • The main procedure has executed a RETURN statement or END statement.
    • The program is exiting because of an error condition not handled by any ON-unit.

    The default ON-unit does nothing and simply returns. If an ON FINISH ON-unit executes a STOP statement, the result is undefined.

  • FIXEDOVERFLOW

    Open PL/I accepts the syntax for the ON FIXEDOVERFLOW statement. However, since there is not adequate hardware support for this condition on the computers supported by Open PL/I, the FIXEDOVERFLOW condition is never raised (unless explicitly raised by the SIGNAL statement).

  • KEY(f)

    The KEY condition is signaled when a READ, REWRITE, or DELETE statement containing a KEY option cannot find a record with the specified key. It is also signaled by a WRITE statement whose KEYFROM option specifies a key of an existing record.

    Just before the condition is signaled, the key value is assigned as the value to be returned by the ONKEY built-in function.

    Returning from the ON-unit resumes execution with the statement following the record I/O statement.

    The following is an example of the ON KEY(f) statement.

    ON KEY(OUTFILE) BEGIN;
       PUT SKIP LIST('INVALID KEY SPECIFIED FOR OUTFILE'); 
       PUT SKIP LIST('KEY WAS'||ONKEY());
    END;
  • OVERFLOW

    The OVERFLOW condition is signaled when the result of an arithmetic operation on a floating-point value exceeds the maximum value that can be represented.

    The maximum values for decimal float values and binary float numbers are described in your Open PL/I User's Guide.

    Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.

  • RECORD(f)

    The RECORD condition can be raised during a READ, WRITE, or REWRITE operation. This condition is raised when:

    • The record variable is smaller than the record size. This may occur for one of the following reasons.
      • The record is larger than the variable in a READ INTO statement. The remainder of the record is lost.
      • The record length specified for a file with fixed-length records is larger than the variable in a WRITE or REWRITE statement. The remainder of the record is undefined. If the variable is a varying-length string, the RECORD condition is not raised if the SCALARVARYING option is applied to the file.
    • The record variable is larger than the record size. This may occur for one of the following reasons.
      1. The record length specified for a file with fixed-length records is smaller than the variable in a READ INTO statement. The remainder of the variable is undefined. If the variable is a varying-length string, the RECORD condition is not raised if the SCALARVARYING option is applied to the file.
      2. The maximum record length is smaller than the variable in a WRITE or REWRITE statement. The remainder of the variable is lost.
      3. The variable in a WRITE or REWRITE statement indicates a zero length. No transmission occurs. If the variable is a varying-length string, the RECORD condition is not raised if the SCALARVARYING option is applied to the file.
    • The record variable length is either zero or too short to contain the embedded key. This occurs because the variable in a WRITE or REWRITE statement is too short to contain the embedded key.
  • SIZE
    Note: SIZE should only be used during application development and removed during production usage, as it has a potential for performance impact.

    The SIZE is disabled by default. Because Open PL/I does not support condition prefixes, which is the language mechanism by which this behavior is enabled, an alternate method is provided.

    The following Open-PLI run-time call is exposed as built-in subroutine:
    dcl __mFp_set_size_condition entry(fixed bin(31) native) external('__mFp_set_size_condition');
    call __mFp_set_size_condition (1);  /*  enables the SIZE condition */
    call __mFp_set_size_condition (0);  /*  disables the SIZE condition */
    
  • UNDEFINEDFILE(f)

    The UNDEFINEDFILE condition is signaled when an error occurs while attempting to open a file.

    Returning from the ON-unit transfers control to the statement following the OPEN statement.

  • USERCONDITION (expression)

    The USERCONDITION (expression) ON-unit handles the condition specified by expression, which must be evaluated to an integer. This ON-unit is invoked in response to execution of the SIGNAL USERCONDITION statement matching the expression value. For more information, see the section SIGNAL Statement.

    The USERCONDITION condition may be signaled using the SIGNAL statement. The value of the expression specified as the USERCONDITION is determined when the ON statement is executed, and not when the condition is signaled. A range of numbers specified in your Open PL/I User's Guide will be allocated for system use.

  • USERCONDITION (SS$_UNWIND)

    The USERCONDITION (SS$_UNWIND) ON-unit handles the condition that is signaled by an UNWIND condition. An UNWIND condition occurs when a nonlocal GOTO forces execution to proceed from a previous block which, in turn, causes frames to be removed from the call stack.

    This is a special case of USERCONDITION (expression). The name SS$_UNWIND is available as a GLOBALREF and must be declared as such.

  • VAXCONDITION (expression)

    The VAXCONDITION (expression) ON-unit is synonymous with the USERCONDITION (expression) ON-unit, and is provided for ease of program conversion. An ON-unit for one can be used to catch a SIGNAL of either.

  • ZERODIVIDE

    The ZERODIVIDE condition is signaled when the divisor in a division operation has a value of zero. The resulting value is undefined.

    Returning from the ON-unit produces an error message and ends program execution by executing a STOP statement.

Restrictions

None.