A NOTREADY condition happens when the operating system (ie, its underlying file system) has a problem performing some operation on a file or device, such as LINEIN() not properly reading the next line from a file. There are many reasons why there may be a problem with a file/device operation, such as LINEOUT() not being able to save a line because you're trying to write to write-protected media.

The default handling for the NOTREADY condition is to ignore it. So for example, let's assume that there is a problem with LINEIN() in the following script, such that REXX raises the NOTREADY condition:

chars = LINEIN(,,1)
SAY chars
REXX ignores the NOTREADY condition since we are not trapping it. Therefore, REXX simply proceeds to the next (ie, SAY) instruction. What does SAY display? It displays an empty string, since that is what LINEIN() returns if there is a problem reading a line.

This is an important item to note. When certain file/device functions have a problem, then the function may return a value that seems to indicate a successful operation. LINEIN hasn't really read in an empty line. Because it has had a problem reading in another line, LINEIN lies to you and tells you that it successfully read another line which happens to be empty. See Clearing a file's error state for more information about errors with files/devices.

The implication here is that, if you want to ensure that you are informed when such a file operation fails, you need to trap the NOTREADY condition (or subsequently verify the operation with STREAM's 'D' option).

If you'd like to use NOTREADY to be informed about file system problems, then you can CATCH NOTREADY. Consider the following script, and again assume that LINEOUT() has a problem (which causes REXX to raise NOTREADY):

/* Display a line. */
err = LINEOUT(, "Hello")
SAY 'Done'
EXIT

/* We jump here if NOTREADY is raised. */
CATCH NOTREADY
   SAY 'NOTREADY raised'
Because LINEOUT has a problem writing the line, REXX raises the NOTREADY condition. REXX knows that you wish to jump to the CATCH NOTREADY when NOTREADY is raised, so instead of proceeding on to the SAY instruction, REXX instead jumps to that label.

Your handler can use the CONDITION() built-in function's 'D' option to fetch the name of the file/device which has a problem. For example:

err = LINEOUT(, "Hello")
SAY 'Done'
EXIT

CATCH NOTREADY
   /* Display the name of the file/device that caused a NOTREADY. */
   SAY 'The stream named "'|| CONDITION('D') ||'" had a problem at line' CONDITION('L')

NOTREADY error/sub-error numbers

Whenever a NOTREADY condition is raised, then an error number, and possibly a sub-error number as well, is associated with that instance of the condition being raised. Each one of the numerous reasons for NOTREADY being raised will produce a different combination of error/sub-error numbers. So, by checking the error/sub-error numbers, you can deduce exactly what went wrong in your script (ie, why the NOTREADY condition was raised).

Your handler can use CONDITION()'s 'E' option to fetch the error and sub-error numbers associated with a given instance of that condition. CONDITION('E') will return the two numbers separated by a dot. The error number will be 11 if NOTREADY has been raised because your script had a problem performing some operation upon a file/device. The sub-error number is set by the operating system, and can be any error number associated with its file system. You'll have to consult the documentation with your operating system to determine what a particular sub-error number means, or use the STREAM() built-in function's 'D' option to retrieve a more descriptive error message.

CATCH NOTREADY
   /* Display the name of the file/device that caused a NOTREADY. */
   SAY 'The stream named "'|| CONDITION('D') ||'" had a problem at line' CONDITION('L')

   /* Display the operating system's error number. */
   PARSE VALUE CONDITION('E') WITH . '.' suberror
   SAY 'Error Number:' suberror

   /* Display an error message from the operating system. */
   SAY STREAM(CONDITION('D'), 'D')
Note: Reginald's CONDITION() function has an additional option. CONDITION('M') will present a pop-up message box containing the name of the file in error as well as the operating system specific error message, the name of the script in which NOTREADY was raised, the source line and line number upon which NOTREADY was raised, and a Help button to bring up a help page for that error. This is preferable to trying to create your own message to present to the person running your script.
CATCH NOTREADY
   /* A preferable way to display a NOTREADY error
    * message using Reginald.
    */
    CONDITION('M')

Trapping NOTREADY in a child script

The Reginald interpreter allows you to trap NOTREADY in any child script you call (as well as any other child script that the first child calls), if that script doesn't trap NOTREADY for itself.

Your script must use a CATCH NOTREADY instruction where you call the child script. If NOTREADY is then raised by the child script, the child script will abort on the line where NOTREADY occurs, and Reginald will raise NOTREADY in your script (on the line where you called the script). In this case, CONDITION('E') returns an error number of 65 to indicate that it was a child script (as opposed to your script) that tried to perform the failed operation upon a file/device. The sub-error number is set by the operating system. CONDITION('D') will return an error message that reports the name of the child script in which NOTREADY was raised, the line number where it occurred in the child script, and the name of the file/device that had the problem.

What this means is that, using the CATCH NOTREADY, if a child script doesn't handle NOTREADY for itself, you can force that child script to be aborted as soon as there is any error with the file system, and have that error automatically reported back to you by REXX.

Here is an example handler that would differentiate between NOTREADY raised in your script versus another script that you called:

CATCH SYNTAX

   /* Get the error and sub-error numbers */
   PARSE VALUE CONDITION('E') WITH error '.' sub

   /* Was NOTREADY raised in a child script we called? */
   IF error == '65' THEN DO

      /* Yes it was. Parse the child script's name, the
       * line number in that script where NOTREADY was
       * raised, and the filename that had the error.
       */
      PARSE VALUE CONDITION('D') WITH . '"' scriptname '"' . 'line ' linenum ': ' streamname

      /* CONDITION('M') is preferable to these SAYs. */
      SAY 'NOTREADY condition raised in "'|| scriptname ||'" at line' linenum ':' streamname
      /* Display the error message from the operating system. */
      SAY STREAM(streamname, 'D')

   END

   /* NOTREADY was raised in this script */
   ELSE DO

      /* CONDITION('M') is preferable to these SAYs. */
      SAY 'NOTREADY condition raised at line' CONDITION('L') ':' CONDITION('D')
      SAY STREAM(CONDITION('D'), 'D')

   END