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"; }

 

posted @ 2020-10-07 16:32  一口一个小馒头  阅读(278)  评论(0编辑  收藏  举报