HP OpenVMS Systems Documentation |
HP BASIC for OpenVMS
|
Previous | Contents | Index |
You use the ERN$ function to return the name of the program unit in which the error was detected. ERN$ returns the name of a main program, SUB, FUNCTION, or PICTURE subprogram, or DEF function. If the PROGRAM statement is used with a user-supplied identifier, the ERN$ value is the specified identifier for the main program. The results of ERN$ are undefined until the program generates an error.
In the following example, control passes to the main program for error handling if the error occurs in the module SUBARC:
HANDLER locat_ern IF ERN$ = "SUBARC" THEN PRINT "ERROR IS ";ERR PRINT "RETURNING TO MAIN PROGRAM FOR ERROR HANDLING" EXIT HANDLER ELSE PRINT "PROGRAM MODULE GENERATING ERROR IS ";ERN$ END IF END HANDLER |
Note that ERN$ is invalid when an error occurs in a subprogram compiled
with the /NOSETUP qualifier.
15.2.5.4 Determining the Error Message Text (ERT$)
You use the ERT$ function to access the message text associated with a specified error number. Use of the ERT$ function is not limited to the scope of the error handler; you can access ERT$ at any time. The following detached handler tests whether the error occurred in a DEF module named TSLFE, and, if so, prints the text of the signaled error and resumes execution:
HANDLER catch_it IF ERN$ = "TSLFE" THEN PRINT ERT$(ERR) CONTINUE ELSE EXIT HANDLER END IF END HANDLER |
HP BASIC provides a built-in function, VMSSTATUS, that returns the originally signaled error before it is translated to a BASIC error. For example, for the BASIC error "End of file on device" (ERR=11), the VMSSTATUS function returns "RMS$_EOF" (RMS end of file). This function is useful when the error is NOTBASIC (ERR=194).
When there is no error pending, VMSSTATUS is undefined. The value returned by this function is the actual signaled error value. If non-BASIC errors are being handled, the VMSSTATUS function might be the only way to find out which error caused the exception.
The following example shows a program that performs file I/O. The first WHEN ERROR block traps any errors that occur while the program is opening the file or requesting user input. The detached handler for this block checks the value of VMSSTATUS to determine the exception that occurred. The inner error handler handles two special errors, BAS$K_RECNOTFOU and BAS$K_RECBUCLOC, separately. If the error signaled does not correspond to one of these, the inner error handler passes control to the outer handler with the EXIT HANDLER statement. The outer handler sets the program status to VMSSTATUS. When the program exits, the operating system displays any status that is of warning severity or greater.
PROGRAM Tester OPTION HANDLE = ERROR EXTERNAL LONG CONSTANT BAS$K_RECNOTFOU, BAS$K_RECBUCLOC DECLARE LONG Final_status MAP (Rec_buffer) & STRING Rec_key = 5, & STRING Rest_of_record = 20 Final_status = 1 WHEN ERROR USE Global_handler OPEN "My_database" FOR INPUT AS FILE #1 & ,INDEXED FIXED & ,ACCESS READ & ,MAP Rec_buffer & ,PRIMARY Rec_key Get_key: INPUT "Record to retrieve"; Rec_key WHEN ERROR IN GET #1%, KEY #0 EQ Rec_key PRINT Rest_of_record USE SELECT ERR CASE = BAS$K_RECNOTFOU PRINT "Record not found" CONTINUE Get_key CASE = BAS$K_RECBUCLOC SLEEP 2% RETRY CASE ELSE EXIT HANDLER END SELECT END WHEN END WHEN HANDLER Global_handler Final_status = VMSSTATUS END HANDLER END PROGRAM Final_status |
The RMSSTATUS function lets you determine which RMS error caused a resulting HP BASIC error. You must specify an open channel as the first parameter to RMSSTATUS. If this channel is not open, the error "I/O channel not open" (ERR=9) is signaled. The second parameter to the function lets you specify either STATUS or VALUE; this parameter is optional. If you do not specify the second parameter, RMSSTATUS returns the STATUS value by default. STATUS represents the RMS STS field and VALUE corresponds to the RMS STV field.
The following example shows an error handler that prints both the status and the value of any RMS error:
WHEN ERROR IN OPEN "file.txt" FOR OUTPUT AS FILE 1% PRINT #1%, TIME$(0%) USE !Error 12 is fatal system I/O failure IF ERR = 12 THEN PRINT "An unexpected RMS error has occurred:" PRINT "Status = "; RMSSTATUS(1%) PRINT "Value = "; RMSSTATUS(1%, VALUE) EXIT HANDLER END IF END WHEN CLOSE #1% GOTO done done: END |
If you want to find an RMS status without knowing which particular
channel to check, you can use VMSSTATUS to get the STATUS value (STS)
if an error has occurred.
15.2.6 Ctrl/C Trapping
Error handling procedures are commonly used to trap user Ctrl/C responses. With Ctrl/C trapping enabled, control is transferred to an error handler if a user presses Ctrl/C during program execution. You enable Ctrl/C trapping in your program by invoking the built-in CTRLC function. For example:
Y% = CTRLC |
After you invoke the CTRLC function, a Ctrl/C entered at the terminal transfers control to the error handler. Once the Ctrl/C is trapped, you can include routines to interact with the program, as shown in the following example:
WHEN ERROR IN Y% = CTRLC OPEN 'FIL_DAT' FOR INPUT AS FILE #1% INPUT "HOW MANY RECORDS"; Rec_read% FOR I% = 1% TO Rec_read% GET #1% PRINT Name$, Address$, Emp_code% PRINT NEXT I% USE !Trap ^C IF (ERR = 28%) THEN PRINT "CURRENT RECORD IS "; I% ELSE EXIT HANDLER END IF CONTINUE Clean_up END WHEN . . . Clean_up: CLOSE #1% PRINT "END OF PROCESSING" END |
SMITH, DEXTER 231 COLUMBUS ST 09341 TRAVIS, JOHN PO BOX 80 64119 ^C THE CURRENT RECORD IS 3 END PROCESSING |
Note that the error condition is still pending until the error handler executes the CONTINUE statement. Therefore, if you press Ctrl/C a second time while the error handler is executing, control returns to the HP BASIC error handler, which terminates the program.
To disable Ctrl/C trapping, use the RCTRLC function. The RCTRLC
function disables only Ctrl/C trapping, not the Ctrl/C interrupts
themselves.
15.2.7 Handling Errors in Multiple-Unit Programs
You can use WHEN ERROR constructs anywhere in your main program or program modules. Procedure and function invocations, such as invocations of DEF and DEF* functions and SUB, FUNCTION, and PICTURE subroutines, as well as non-BASIC programs, are valid within protected regions. GOTO and GOSUB statements are valid within handlers provided that the target is within the handler, an outer handler, or an unprotected region. Note, however, that a detached handler cannot appear within DEF or DEF* functions without the associated protected region.
When an error occurs within nested protected regions, HP BASIC maintains the same priorities for handler use; control always passes to the handler associated with the innermost protected region in which the error occurred. When an exception occurs, all handlers for any outer WHEN ERROR blocks are processed before the program reverts to default error handling. Outer handlers are invoked when an inner handler executes an EXIT HANDLER statement. When there are no more outer handlers, and the outermost handler executes an EXIT HANDLER statement, program control reverts to the handler associated with the calling routine. For example:
SUB LIST(A$) WHEN ERROR USE sub_handler OPEN A$ FOR INPUT AS FILE #12% Get_data: LINPUT #12%, B$ PRINT B$ GOTO Get_data END WHEN HANDLER sub_handler !Trap end of file IF ERR <> 11% THEN EXIT HANDLER END IF END HANDLER CLose_up: CLOSE #12% END SUB |
You can call a subprogram while an error is pending; however, if you do, the subprogram cannot resignal an error back to the calling program. If the subprogram tries to resignal an error, HP BASIC signals "Improper error handling" and program execution terminates.
The following rules apply to error handling in function definitions:
For example:
WHEN ERROR IN . . . Invoke_def: A% = FNIN_PUT%("PROMPT") USE PRINT "ERROR"; ERT$(ERR%); IF ERN$ = "FNIN_PUT" THEN PRINT "IN FUNCTION" CONTINUE ELSE PRINT "IN MAIN" CONTINUE Invoke_def END IF END WHEN Main_code: DEF FNIN_PUT%(P$) WHEN ERROR IN PRINT P$ INPUT LINE_IN$ FNIN_PUT% = INTEGER(LINE_IN$) USE IF ERR = 50 THEN RETRY ELSE EXIT HANDLER END IF END WHEN END DEF |
If you invoke a GOSUB statement or a DEF* function from within a protected region and the invoked procedure is outside of any protected region, all pending errors are handled by the WHEN ERROR handler unless a previously executed ON ERROR statement specifies otherwise. |
The CAUSE ERROR statement allows a program to artificially generate an error when the program would not otherwise do so. You can force any HP BASIC run-time error. You must specify the number of the error the compiler should force; the error numbers are listed in Appendix B. The following statement forces an end-of-file error (ERR=11) to occur:
CAUSE ERROR 11% |
You can use this feature to debug an error handler during program development, as shown in the following example:
WHEN ERROR IN . . . CAUSE ERROR 11% . . . USE SELECT ERR CASE = 11% PRINT "Trapped an end of file on device" CONTINUE CASE ELSE EXIT HANDLER END WHEN |
HP BASIC supports ON ERROR statements as an alternative to WHEN blocks primarily for compatibility with existing programs. WHEN ERROR blocks are similar to declarative statements in that they do not depend on run-time flow of control. The ON ERROR statements, however, affect error handling only if the statements execute at run time. For example, if a GOTO statement precedes an ON ERROR statement, the ON ERROR statement will not have any effect because it does not execute.
WHEN ERROR blocks let you handle errors that occur in a specific range of statements. ON ERROR statements let you specify a general error handler that is in effect until you specify another ON ERROR statement or until you pass control to the HP BASIC error handler.
For all current program development, it is recommended that you use WHEN ERROR constructs for user-written error handlers. Mixing WHEN ERROR constructs and ON ERROR statements within the same program is not recommended. The ON ERROR statements are supported for compatibility with other versions of BASIC available from HP. It is important to note that all of these statements are illegal within a protected region, or an attached or detached handler. |
The ON ERROR statements are documented in the HP BASIC for OpenVMS Reference Manual. This section briefly describes the main features of the ON ERROR statements.
The ON ERROR statements can be used to transfer control to a labeled block of error handling code. If you have executed an ON ERROR statement and an error occurs, the ON ERROR statement immediately transfers control to the label or line number that starts the error handling code. Otherwise, the ON ERROR statement specifies the branch to be taken in the event of an error.
There are three forms of the ON ERROR statement:
The ON ERROR GOTO statement is usually placed before any other executable statements. The following example clears end-of-file errors and passes all other errors back to the HP BASIC default error handling procedures:
5 ON ERROR GOTO Error_handler . . . Error_handler: !Trap end of file on device IF ERR = 11 THEN RESUME 1000 ELSE ON ERROR GO BACK END IF |
The ON ERROR GOTO statement remains in effect after your program successfully handles an error. When the system signals another error, control once again transfers to the specified error handler.
Every ON ERROR error handler must end with one of the following statements:
If none of these statements is present, the HP BASIC error handler aborts your program with the fatal error "Error trap needs RESUME" as soon as an END, END SUB, END DEF, END FUNCTION, END PROGRAM, or END PICTURE statement is encountered. The RESUME statement, like the RETRY and CONTINUE statements, clears the error condition.
You can resume execution at any line number or label that is in the same module as the RESUME statement, unless that line or target is inside a DEF function, a WHEN ERROR protected region, or a handler. In general, RESUME without a target transfers control to the beginning of the program block where the error occurred.
For more information about the RESUME statement, see the HP BASIC for OpenVMS Reference Manual.
Using both ON ERROR statements and WHEN ERROR constructs in the same program is not recommended. However, when this is the case, the order of handler priorities is as follows:
For information about specific run-time errors, see Appendix B.
Previous | Next | Contents | Index |