ibm-midrangerpgle

How to handle errors in RPGLE?


I am trying to come up with a good approach to handle errors in an RPGLE program with a number of SubProcedures.

dcl-proc getWorkKeyString;

   dcl-pi *n ind ;
    workKeyArray likeDS(parentWorkKeyArray) dim(500);
    workKeyString like(ISWCDUPDS.IWKEY_ISWC);
   end-pi;

   index = 1;

   dow (index < 500);

      monitor;
        if ( workKeyArray(index).workKey <> 0);

                if (index > 1);
                    workKeyString = %Trim(workKeyString)  + '|';
                endif;
                workKeyString = %Trim(workKeyString) + %char(workKeyArray(index).workKey);

        endif;
      index = index + 1;
      on-error;
        return cFalse;
      endmon;

   enddo;

   return cTrue;
end-proc;

As you can see, I have enclosed the do while body in a monitor group. If some error comes up, a false is returned from the sub procedure to indicate error. But please let me know if this looks like a good approach.


Solution

  • One of the wonderful things about the IBM i is that it's generally exception-based rather than return-code based.

    By monitoring for all exceptions and returning an indicator, you are creating a return-code based system.

    With a return-code based system, you have to code like this in every procedure:

    rc = someProc();
    if rc > 0 
       ... return rc
    else
      ... continue with the work
    endif
    rc = someOtherproc();
    if rc > 0
       ... return error
    else
       ... continue with the work
    endif
    

    It's very easy to forget to check the return code:

    rc = someProc();
    rc = someOtherproc(); // What if someProc failed?!
    

    It's also very easy not to even bother getting the return code:

    someProc();
    someOtherproc(); // What if someProc failed?!
    

    With an exception-based system, if I have some way of handling the error:

    monitor;
       someProc();
       someOtherproc();
    on-error;
       ... handle the error
       ... I could even use SND-MSG *ESCAPE to raise a new exception
           after I handle the error
    endmon;
    

    If I want to let my caller (or its caller) handle the exception, I can just let my procedure end when it gets the exception, and let the exception percolate:

    someProc();
    someOtherproc();