Error-Handling Techniques

How FEEDBACK= Differs from _IORC_ and _FDBK_

The FEEDBACK= option specifies a SAS variable that is set to the VSAM feedback code. The variable is set only when VSAM encounters a logical error. That is, the variable's value is 0 until a logical error occurs. The nonzero value indicates what type of logical error was detected. Some Common Causes of Logical Errors describes the feedback codes that are most likely to be returned in the FEEDBACK= variable.
Note that both the _FDBK_ and the FEEDBACK= variables are set to the VSAM feedback code when a logical error occurs. The distinction between the two values is that only by specifying the FEEDBACK= variable (and resetting it) can you continue to process and detect later errors that might occur. The ability to reset the FEEDBACK= variable after taking appropriate action to handle the error is very significant. For this reason, it is strongly recommended that you use the FEEDBACK= option for all VSAM data sets in which logical errors might occur.
Other distinctions are that _FDBK_ is also set if the following occurs:
  • when VSAM detects a physical error.
  • when VSAM sets a zero return code in certain situations.
    You get a nonzero _FDBK_ with a zero _IORC_ when you try to create a duplicate key in an alternate index.
The FEEDBACK= variable has a nonzero value only when a logical error occurs.

Using the FEEDBACK= Option

The FEEDBACK= option in the INFILE statement specifies a SAS variable that is set to the VSAM feedback code when VSAM detects a logical error. You can determine what caused the error by inspecting the FEEDBACK= variable value. You can then design program logic that takes appropriate action depending on the value of the FEEDBACK= variable. You must reset the values of both the FEEDBACK= variable and the _ERROR_ variable to 0 in order to continue processing.
Resetting the variable to 0 enables you to continue processing in a meaningful way. That is, you can continue both to read and write records and detect other errors in the DATA step. If you do not reset the FEEDBACK= and _ERROR_ variables before the next INPUT or PUT statement, SAS assumes that your program cannot handle the error condition, and it executes the following:
  1. prints a message that includes information about the data set and the VSAM logical error code on the SAS log
  2. terminates the DATA step
The DATA step also terminates when the FEEDBACK= option is not specified, and a logical error occurs while it attempts to write with a PUT statement.
You must use the FEEDBACK= option to use the key-testing techniques for a KSDS (described in Processing a KSDS in a SAS Job) and the slot-testing techniques for an RRDS (described in Processing an RRDS in a SAS Job).
VSAM cannot return data to the input buffer when there is a logical or physical I/O error. Subsequent INPUT statements cannot read from an empty INPUT buffer, which leaves variables without values. To avoid this situation, test the values of _IORC_ and the FEEDBACK= variable by using a trailing @ with the INPUT statement that initiates the VSAM read request:
infile indata vsam feedback=NOERROR;
      input @;          /* Read: look at values of FEEDBACK= variable */
                        /* and _IORC_.  If OK, finish reading values  */
                        /* into variables and write them to the SAS   */
                        /* print file.                                */
      if _IORC_ = 0 and NOERROR=0 then do;
         input var1 $ var2 var3 $;
         file print;
         put var1 var2 var3;
      end;               /* If _IORC_ and NOERROR=0 */
      else if _IORC_= 12 then do;
                          /* Physical error has occurred.             */
                          /* INPUT buffer is empty: nothing to read.  */
            _ERROR_ = 0;  /* Reset the _ERROR_ variable.              */
            file log;     /* Write message on the SAS log.            */
            put 'Physical error has occurred for observation ' _N_ '.'

                'I/O return code is ' _IORC_ '.';
            input;        /* Ignore blank buffer: release trailing @. */
            return;
      end;                /* Else: _IORC_=12 */
      else if NOERROR ^= 0 then do;
                          /* Logical error has occurred.              */
                          /* INPUT buffer is empty: nothing to read.  */
            _ERROR_ = 0;
            file log;     /* Write message on the SAS log.            */
            put 'Logical error has occurred for observation ' _N_ '.'
                'Feedback code is ' noerror '.';
            NOERROR=0;   /* Reset FEEDBACK= variable back to 0.       */
            input;       /* Ignore blank buffer: release trailing @   */
            _ERROR_ = 0; /* Above INPUT stmt. sets both the _ERROR_   */
            NOERROR=0;   /* and the FEEDBACK= variables. Both need    */
                         /* to be reset to 0 again.                   */
            return;
      end;               /* Else: NOERROR ^= 0 */
      ...more SAS statements...
Using the INPUT @ statement gives you the opportunity to examine the FEEDBACK= variable for a nonzero value, which indicates that a logical error has occurred. If both the _IORC_ and the FEEDBACK= variables are zero, continue with the INPUT statement to read data into variables.
Notice that the _ERROR_ and the FEEDBACK= variable, NOERROR, need to be reset to 0 twice when set to a nonzero value by an INPUT statement with a trailing @. They need to be reset to 0 the first time in order to continue processing. The processing continues by releasing the held record from the input buffer with an INPUT statement without a trailing @. This sets the _ERROR_ and FEEDBACK= variables to nonzero values again. Therefore, they need to be reset to 0 a second time in order to proceed.
You might want to print error messages warning you that either a physical error was encountered (if _IORC_ is 12) or a logical error was encountered (if the FEEDBACK= variable is not 0). You might also design logic to handle specific, anticipated FEEDBACK= variable values.