AX2012 Error handling in AIF Service (错误异常处理)
AIF Service自带有Try-Catch并且是包含在事务里面的,所以如果我们尝试在AIF方法里面使用Try-Catch来捕获异常,然后处理,其实效果并不是你想要的样子。
就像下面的的Job一样,最外层的try-catch就当作是AIF Service自带的try-catch。 第二层的try-catch就当作是我们在AIF里面使用的try-catch来捕获异常。
static void Job109(Args _args) { str error; SysInfoLogEnumerator infoLogEnum; ; try { ttsBegin; try { ttsBegin; throw error("抛出异常"); ttsCommit; } catch (Exception::Error) { ttsAbort; infoLogEnum = SysInfologEnumerator::newData(infolog.infologData()); while(infoLogEnum.moveNext()) { error += infoLogEnum.currentMessage(); } info(strFmt("层级2Error:%1", error)); } ttsCommit; } catch(Exception::Error) { ttsAbort; error = ""; infoLogEnum = SysInfologEnumerator::newData(infolog.infologData()); while(infoLogEnum.moveNext()) { error += infoLogEnum.currentMessage(); } info(strFmt("层级1Error:%1", error)); } }
执行上面的Job, 按照我们的预期,这个应该info “层级2Error: 抛出异常”。然而从下面的执行结果可以到,我们抛出的异常却是被最外层的try-catch捕捉,而非我们想要的里层try-catch。
解决方法就是在写用户想要的try-catch之前先抵消最外层try-catch自带的事务。 将上面的修改一下
static void Job109(Args _args) { str error; SysInfoLogEnumerator infoLogEnum; int ttslevel; ; try { ttsBegin; ttslevel = appl.ttsLevel(); while (appl.ttsLevel() > 0) { ttsCommit; } try { ttsBegin; throw error("抛出异常"); ttsCommit; } catch (Exception::Error) { ttsAbort; infoLogEnum = SysInfologEnumerator::newData(infolog.infologData()); while(infoLogEnum.moveNext()) { error += infoLogEnum.currentMessage(); } info(strFmt("层级2Error:%1", error)); } while (ttslevel > 0) { ttslevel--; ttsBegin; } ttsCommit; } catch(Exception::Error) { ttsAbort; error = ""; infoLogEnum = SysInfologEnumerator::newData(infolog.infologData()); while(infoLogEnum.moveNext()) { error += infoLogEnum.currentMessage(); } info(strFmt("层级1Error:%1", error)); } }
再执行一次:这时候从得到得结果可以出来,抛出的异常如我们预期的那样被内层的try-catch的捕捉到了。
所以一般如果你想要在AIF Service里面进行错误异常处理,可以使用下面的代码格式:
代码里面使用Infolog.infologData()来获得信息日志里面的信息(error,info),使用这种方式去获取日志信息的好处就是我们可以直接在AIF Service方法里面直接调用系统原来自带的一些方法以及方法原本自带的validate,而不用特地的为它们再写一次validate, 使用下面的代码,所有在Try catch里面需要被抛出的错误,请都使用throw error抛出,不可以使用return哦。
[SysEntryPointAttribute(true), AifCollectionTypeAttribute('param1', Types::String) AifCollectionTypeAttribute('return', Types::Class)] public str serviceOperation(String param1) { SysInfoLogEnumerator infoLogEnum;
int ttslevel; str err; ; ttslevel = appl.ttsLevel(); // 和系统自带的ttsBegin先匹对关闭 while (appl.ttsLevel() > 0) { ttsCommit; } // 在这后面写你自己的Try-Catch BEGIN, 当然这里你也可以转到一个方法,在该方法里面使用try - catch也是一样的效果 try { ttsBegin; ttsCommit; } catch { ttsAbort;
// 获取系统info出来的各种信息 infoLogEnum = SysInfoLogEnumerator::newData(infolog.infologData()); while(infoLogEnum.moveNext()) { err += infoLogEnum.currentMessage(); } } // 在这前面写你自己的Try-Catch END // 因为之前加入了自己的代码关闭了系统自带的ttsBegin, 所以这里也需要加入下面的代码和系统自带的ttsCommit匹对避免出错 while (ttslevel > 0) { ttslevel--; ttsBegin; } return err ? err : "Success"; }