tips:revmedia:r66

Low-Level Error Handling

Published ByDateVersionKnowledge LevelKeywords
Revelation Technologies10 OCT 19902.XEXPERTBFS/MFS, FSMSG, STDIOERR, STDIOERR_CTL

One of the design goals of Advanced Revelation 2.0 was to provide tighter control over low level I/O errors. That goal was realized. This Technical Bulletin provides information about handling low level I/O errors.

In order to be compatible with 2.0, all BFSs and MFSs must adhere to a new error-reporting protocol. Details of the protocol are provided in Technical Bulletin #43.

One part of the protocol deals with setting STATUS(). All I/O failures set STATUS() to one of the following values, indicating the severity of the failure.

CodeDescription
0Logical error-the operation failed for logical reasons. For example, a security MFS might fail a write if the user's privelege level was not high enough.
1Physical error - the error may be transient, a retry may safely be executed. For example, a BFS dedicated to file access via phone lines might find a problem with the line. Retrying the operation might succeed.
2Fatal error - the operation should not be retried until the problem has been corrected. This would be the case, for example, when the disk has been corrupted.

In addition to setting STATUS(), BFSs and MFSs set @FILE.ERROR, which contains detailed information about the error. The layout of @FILE.ERROR is:

FieldDescription
1The error code. See the equate records in the INCLUDE file for a listing of the codes and their meanings.
2Detail support for the error. For example, a record key or a file name might be given. Whether or not this field is required depends on the error code. See the INCLUDE file for specific errors.
3Additional error text, if needed.

Whenever an I/O operation fails, control is passed back to the calling program on the ELSE branch. This is where you typically include error processing. To relieve you of having to deal with all possible errors, the system has a default error handler: FSMSG.

FSMSG allows you to handle errors selectively or not at all. For example, your program might have code like this:

READ REC FROM FILE_IN_FILE ELSE
  IF @FILE.ERROR<FSCODE$> = FS_REC_DNE$ ELSE
     FSMSG()
  END
END

In the example above, the program calls FSMSG for all errors other than "Record does not exist", which is simply ignored.

DELETE REC FROM SOURCE_FILE ELSE
  FSMSG()
END

In this example all DELETE failures are passed to FSMSG.

Low level errors differ from high-level errors in that application programs are not generally expected to have to interpret them. These errors are expected to occur so infrequently that your programs should rarely, if ever, see them.

To deal with low level errors, a standard error handler is provided, STDIOERR.

STDIOERR is called under the following circumstances:

  • All logical failures of DELETE and WRITE operations that do not have a branch. Even if the only branch statement provided is THEN, the error handler will not be called.
    Note: A special case is allowed for attempts to delete non-existent records. If such an attempt is made, STDIOERR is not called.
  • All physical and fatal DELETE and WRITE errors.
  • All physical or fatal errors on READ or READO statements.
  • All physical or fatal errors on READNEXT.

The text displayed by STDIOERR and the actions to be performed come from a record in the SYS.HELP file, STDIOERR_CTL. The layout of this record is:

FieldDescription
1Read error text "Reading"
2Write error text "Writing"
3Delete error text "Deleting"
4Readnext error text "Readnexting"
5Conjuction text "in file"
6Logical error prompt
7Physical error prompt
8Fatal error prompt
9Action keys
10Action codes
11Action commands
12Escape action code
13Escape action command

Fields 6 - 8 are multivalued. Each field has this layout:

ValueDescription
1Error level text Ä "Logical error"
2Prompt text Ä "Break to debugger, Continue? (B/C)"
3Action character list Ä "BC"

Fields 9 - 11 are associated multivalues. Each field is related to the others. The code in value one of field 10 corresponds to the action key in value one of field 9. When the user presses the action key, the corresponding code (and command) is executed.

Fields 12 and 13 define the action to take place when the user presses [Esc].

Three codes are predefined. No command is required if these codes are used.

CodeDescription
1ABORT ALL
2Break to Debugger
3Do nothing, return control to the program

If you execute your own program via a CATALYST code and command, information about the error can be found in @ANS. That information is:

FieldDescription
1Filing system code
2Error level (from STATUS(), see above)
3Record key
4Revelation file name

By modifying STDIOERR_CTL, you can control the options presented to the user and what happens when as option is selected.

If you modify STDIOERR_CTL, there are several issues to keep in mind.

First, remember that STDIOERR is global. It will be called for all low-level errors, not just those for a specific process or file. Your changes must be applicable to all files and all processes.

Second, STDIOERR requires user interaction. Even if a user has no choices, a message requiring input from the user is displayed.

Third, the action keystrokes must be unique. That is, you cannot have the letter "B" mean one thing for logical errors and another for physical errors without writing your own routine. See Figure 1 for an example of how to decide what action to perform.

Finally, note that the processing for [Esc] is the same for all error levels.

It is possible for your programs to prevent calls to STDIOERR. If you elect to take responsibility for all errors, including fatal errors, you can set the system variable @FILE.ERROR.MODE to 1 (true).

If STDIOERR would normally be called and @FILE.ERROR.MODE is true, control is returned to your program and you can deal with the error.

@FILE.ERROR.MODE is reset to false everytime you go down an execution level and whenever a RESET is executed. However, you should exercise caution whenever you set @FILE.ERROR.MODE, to avoid affecting programs that do not deal with low level errors. See Figure 2 for an example of how to use @FILE.ERROR.MODE.

Figure 1

SUBROUTINE ERR_HANDLER

/* A program that allows the same action keystroke to be used for different
severity levels. */

ERR_INFO  = @ANS
ERR_LEVEL = ERR_INFO<2>

BEGIN CASE
  CASE ERR_LEVEL = 0
    /* Logical error. */
  CASE ERR_LEVEL = 1
    /* Physical error. */
  CASE ERR_LEVEL = 2
    /* Fatal error. */
END CASE
RETURN

Figure 2

EQU TRUE$ TO 1
EQU FALSE$ TO 0

(...)

DONE = FALSE$
LOOP
  READNEXT KEY FROM FILE_CUST ELSE
    DONE = TRUE$
  END
UNTIL DONE
  @FILE.ERROR.MODE = TRUE$
  READ REC FROM FILE_CUST THEN
    /* Normal record processing. */
  END ELSE
    /* Error of some sort. */
    BEGIN CASE
       CASE STATUS() = 0
         /* Logical error. */
       CASE STATUS() = 1
         /* Physical error. */
       CASE STATUS() = 2
         /* Fatal error. */
    END CASE
  END
  @FILE.ERROR.MODE = FALSE$
REPEAT
  • tips/revmedia/r66.txt
  • Last modified: 2024/06/19 20:20
  • by 127.0.0.1