Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Openedge 从处理块外的过程捕获错误_Openedge_Progress 4gl - Fatal编程技术网

Openedge 从处理块外的过程捕获错误

Openedge 从处理块外的过程捕获错误,openedge,progress-4gl,Openedge,Progress 4gl,我有以下代码(为了便于说明,对其进行了简化)。我在proc1、proc2和proc3的不同DB表中创建记录。我试图实现的是…如果我在任何时候在临时表中循环时遇到错误(即使在我已经创建了一堆DB记录之后),我希望回滚所有内容,以便不创建任何记录。如果proc1、proc2和proc3没有问题,它会捕获错误,但我无法确定如何将这些错误传递给主处理块,以便它理解并回滚所有内容。换句话说,消息('error@main trans block')永远不会弹出,因此已经创建的记录保留在数据库中。事实上,没有

我有以下代码(为了便于说明,对其进行了简化)。我在proc1、proc2和proc3的不同DB表中创建记录。我试图实现的是…如果我在任何时候在临时表中循环时遇到错误(即使在我已经创建了一堆DB记录之后),我希望回滚所有内容,以便不创建任何记录。如果proc1、proc2和proc3没有问题,它会捕获错误,但我无法确定如何将这些错误传递给主处理块,以便它理解并回滚所有内容。换句话说,消息('error@main trans block')永远不会弹出,因此已经创建的记录保留在数据库中。事实上,没有任何东西会倒退

DO TRANSACTION ON ERROR UNDO, THROW:

    FOR EACH tt1:

        RUN proc1.

        FOR EACH tt2 WHERE tt2.field1 EQ tt1.field1:

            RUN proc2.

            FOR EACH tt3 WHERE tt3.field2 EQ tt2.field2:

                RUN proc3.

            END.

        END.

    END.

    CATCH e AS PROGRESS.Lang.AppERROR:

        MESSAGE 'error @ main trans block'
            VIEW-AS ALERT-BOX INFO BUTTONS OK.

    END CATCH. 

END.

PROCEDURE proc1.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc1 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

PROCEDURE proc2.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc2 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

PROCEDURE proc3.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc3 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

TIA有几个潜在问题

首先,需要在不使用
NO-UNDO
标志的情况下定义临时表tt1和tt2

其次,FOR EACH块使用默认的错误处理行为,即
ON error UNDO,NEXT.
因此在FOR EACH块中引发的错误将导致当前迭代被撤销,而不是整个事务

我建议添加

BLOCK-LEVEL ON ERROR UNDO, THROW . 
到节目的顶端。或者至少

ROUTINE-LEVEL ON ERROR UNDO, THROW . 
与错误撤消时的
组合,在每个
块的所有
上抛出
选项


自OpenEdge 11.3(或更高版本)以来,
块级
错误处理选项可用。

嗨,迈克,谢谢你的建议。这有点奏效,但我认为我解释得不对。我在过程的顶部添加了块级别,现在整个过程都被撤消了。但是,我只需要一个特定的块和该块调用的所有内部过程就可以撤消。我希望避免在一个单独的文件中分离这个逻辑。肯定有一种方法可以撤销特定的代码块以及从代码内部调用的所有代码?这就是块标签的用途。在(迭代)块之前,执行类似于my label的操作:FOR EACH。。。。然后撤销,离开my-label。嗨,Mike,如果我调用一个从迭代块中执行某些操作(例如,创建永久数据库记录)的过程,这种方法是否有效?例如createBlock:对于每个…在错误撤消createBlock时,保留createBlock:运行createProc。终止createProc。。。。。创建永久数据库表。结束程序。如果我已经创建了10个DB记录,并且在FOR EACH的第11次迭代中,我在createProc中有一个错误,它会回滚(取消创建)之前创建的所有10个记录吗?如果您有一个外部事务块,并且该块是您撤消的,那么留下yesHi Mike,我添加了块标签,它工作正常。谢谢你的帮助!