General Error Control

Sometimes, you might want to process or step over errors. To do this, put all the code into modules and push a code to abort if the error count exceeds some maximum. Often, you might submit a batch job and get a trivial mistake that causes an error, but you do not want to cause the whole run to fail because of it. On the other hand, if you have many errors, you do not want to let the routine run.

In the following example, up to three errors are tolerated. A singular matrix $\mb {A}$ is passed to the INV function, which would, by itself, generate an error message and issue a pause in the module. This module pushes three RESUME statements, so that the first three errors are tolerated. Messages are printed and execution is resumed. The DO loop in the module OOPS is executed four times, and on the fourth iteration, an ABORT statement is issued and you exit IML.

   proc iml;
   a={3 3, 3 3};                             /* singular matrix */
      /*                                                        */
      /* GENERAL ERROR CONTROL -- exit iml for 3 or more errors */
      /*                                                        */
    start;                         /* module will be named MAIN */
       errcode = {" if errors >= 0 then do;",
                  "    errors = errors + 1;",
                  "    if errors > 2 then abort;",
                  "    else do; call push(errcode); resume; end;",
                  " end;" } ;
       call push (errcode);
       errors = 0;
       start oops;                         /* start module OOPS */
          do i = 1 to 4;
              b = inv(a);
          end;
       finish;                                   /* finish OOPS */
       run oops;
    finish;                                      /* finish MAIN */
    errors=-1;                                   /* disable     */
    run;

The output generated from this example is as follows:

      ERROR: (execution) Matrix should be non-singular.

      Error occurred in module OOPS     at line    41 column  17
      called   from    module MAIN     at line    44 column  10
      operation : INV                  at line    41 column  24
      operands  : A

     A             2 rows      2 cols    (numeric)

              3         3
              3         3

      stmt: ASSIGN                     at line    41 column  17

     Paused in module OOPS.

     Resuming execution in module OOPS.
     ERROR: (execution) Matrix should be non-singular.

      Error occurred in module OOPS     at line    41 column  17
      called   from    module MAIN     at line    44 column  10
      operation : INV                  at line    41 column  24
      operands  : A

     A             2 rows      2 cols    (numeric)

              3         3
              3         3

      stmt: ASSIGN                     at line    41 column  17

     Paused in module OOPS.

     Resuming execution in module OOPS.
     ERROR: (execution) Matrix should be non-singular.
      Error occurred in module OOPS     at line    41 column  17
      called   from    module MAIN     at line    44 column  10
      operation : INV                  at line    41 column  24
      operands  : A

     A             2 rows      2 cols    (numeric)

              3         3
              3         3

      stmt: ASSIGN                     at line    41 column  17

     Paused in module OOPS.
     Exiting IML.

Actually, in this particular case it would probably be simpler to put three RESUME statements after the RUN statement to resume execution after each of the first three errors.