我正在尝试想出一种好方法来处理带有多个子过程的 RPGLE 程序中的错误。
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;
如您所见,我已将 do while 主体包含在监视器组中。如果出现错误,子过程将返回 false 以指示错误。但请告诉我这是否是一个好方法。
IBM i 的一大优点是它通常基于异常而不是基于返回代码。
通过监视所有异常并返回指示器,您正在创建一个基于返回代码的系统。
使用基于返回码的系统,您必须在每个过程中进行如下编码:
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
很容易忘记检查返回码:
rc = someProc();
rc = someOtherproc(); // What if someProc failed?!
也很容易不用费心去获取返回码:
someProc();
someOtherproc(); // What if someProc failed?!
使用基于异常的系统,如果我有某种方法处理错误:
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;
如果我想让我的调用者(或其调用者)处理异常,我可以让我的过程在获得异常时结束,并让异常渗透:
someProc();
someOtherproc();
我考虑以基于意见的方式结束这个问题...RPG 中的错误处理与许多语言一样并不是一刀切的。
我同意这个评论,你对 MONITOR 的使用似乎不是很有用。一般来说,您会监视如此小的代码段中预期的和可处理的错误。
我建议看一下 谁知道你可以用 RPG IV 做到这一点?中的 第 7 章 - 异常和错误处理适合现代程序员的现代 RPG 红皮书(又名“RPG 巫师”红皮书)。我一直很喜欢“投掷/接住/渗透”的想法;上面链接的“RPG Wizard”红皮书的最新版本中对此进行了描述。随着 2022 年春季引入
SND-MSG
和 ON-EXCP
操作码,投掷/接住变得更加容易
对 Throw/Catch 的一个警告是,与大多数(所有?)其他语言一样,RPG 中的异常处理是昂贵的;
还要考虑 IBM 如何编码其 API。