美文网首页
第四十四章 Caché 变量大全 $ZTRAP 变量

第四十四章 Caché 变量大全 $ZTRAP 变量

作者: Cache技术分享 | 来源:发表于2021-02-23 07:02 被阅读0次

    第四十四章 Caché 变量大全 $ZTRAP 变量

    包含当前错误陷阱处理程序的名称。

    大纲

    $ZTRAP
    $ZT
    

    描述

    $ZTRAP包含当前错误陷阱处理程序的行标签名和/或例程名。有三种方法可以设置$ZTRAP:

    • SET $ZTRAP=“location”
    • SET $ZTRAP=“*location”
    • SET $ZTRAP=“^%ET” or “^%ETN”

    在这里,位置可以指定为标签(当前例程中的行标签)、^routine(指定外部例程的开始)或label^routine(指定外部例程中的指定标签)。

    然而,$ZTRAP=label^routine不能用于程序块。过程块中的$ZTRAP不能用于转到过程体之外的位置;过程块中的$ZTRAP只能引用该过程块中的一个位置

    Location

    使用设置命令,可以将位置指定为带引号的字符串。

    • 在例程中,可以将位置指定为标签(当前例程中的行标签)、^routine(指定外部例程的开始)或label^routine(指定外部例程中的指定标签)。不要在引用过程或过程中的标签的例程中指定位置。这是一个无效位置;当InterSystems IRIS试图执行$ZTRAP时,会导致运行时错误。
    • 在过程中,可以将位置指定为标签;过程块中私有标签。过程块中的$ZTRAP不能用于转到过程体之外的位置;过程块中的$ZTRAP只能引用该过程块中的一个位置。因此,在过程中,不能将$ZTRAP设置为^routinelabel^routine.尝试这样做将导致<SYNTAX>错误。

    在过程中,将$ZTRAP设置为私有标签名,但是$ZTRAP值不是私有标签名;它是从过程标签(过程的顶部)到私有标签的行位置的偏移量。例如,+17^myproc.

    注意:$ZTRAP在某些情况下(而不是在过程中)为label + offset提供传统支持。这个可选的+ offset是一个整数,指定要从label偏移的行数。标签必须在相同的例程中。不建议使用+offset,它可能会导致编译警告错误。 InterSystems建议您在指定位置时避免使用行偏移量。

    调用过程或IRIS SYS%例程时,不能指定+偏移量。如果尝试这样做,则InterSystems IRIS会发出错误。

    $ZTRAP位置必须在当前名称空间中。 $ZTRAP不支持扩展的例程引用。

    如果指定了不存在的行标签(当前例程中不存在的位置),则会发生以下情况:

    • 显示$ZTRAP:在例程中,$ZTRAP包含label ^ routine。例如,DummyLabel^MyRou。在一个过程中,$TRAP包含最大可能的偏移量:+ 34463 ^ MyProc
    • 调用$ZTRAP:InterSystems IRIS发出<NOLINE>错误消息。

    每个堆栈级别可以有其自己的$ZTRAP值。设置$ZTRAP时,系统会将$ZTRAP的值保存为先前的堆栈级别。当前堆栈级别结束时,InterSystems IRIS会恢复该值。要在当前堆栈级别启用错误陷阱,请通过指定$ZTRAP的位置将其设置为错误陷阱处理程序。例如:

    
    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP()
    ClassMethod ZTRAP()
    {
        IF $ZTRAP="" {
            WRITE !,"$ZTRAP not set"
        } ELSE {
            WRITE !,"$ZTRAP already set: ",$ZTRAP
            SET oldtrap=$ZTRAP 
        }
        SET $ZTRAP="Etrap1^Handler"
        WRITE !,"$ZTRAP set to: ",$ZTRAP
        //  program code
        SET $ZTRAP=oldtrap
        WRITE !,"$ZTRAP restored to: ",$ZTRAP
    }
    

    发生错误时,此格式将展开调用堆栈,并将控制权转移到指定的错误陷阱处理程序。

    在SqlComputeCode中,不要设置$ZTRAP = $ZTRAP。这可能导致事务处理和错误报告方面的重大问题。

    要禁用错误捕获,请将$ZTRAP设置为空字符串(“”)。这将清除在当前DO堆栈级别设置的所有错误陷阱。

    注意:在“终端”提示符下使用ZTRAP仅限于当前代码行。 `SETZTRAP命令和生成错误的命令必须在同一行代码中。终端在每个命令行的开头将$ZTRAP`还原为系统默认值。

    *Location

    在例程中,可以选择在发生错误后保留调用堆栈。为此,请在位置之前和双引号内放置一个星号(*)。该表格不适用于程序。尝试这样做会导致<SYNTAX> 错误。只能在不是过程的子例程中使用此示例中的:

    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP()
    ClassMethod ZTRAP()
    {
    Main
        SET $ZTRAP="*OnError"
        WRITE !,"$ZTRAP set to: ",$ZTRAP
        // program code
    OnError
        // Error handling code
        QUIT
    }
    

    这种格式只会导致转到$ZTRAP中指定的行标签;$STACK$ESTACK保持不变。$ZTRAP错误处理例程的上下文框架与发生错误的上下文框架相同。但是,InterSystems IRIS会将$ROLES重置为设置$ZTRAP的执行级别的有效值;这会阻止$ZTRAP错误处理程序使用在建立错误处理程序后授予例程的提升权限。完成$ZTRAP错误处理例程后,InterSystems IRIS将堆栈展开到上一个上下文级。这种形式的$ZTRAP对于分析意外错误特别有用。

    请注意,星号设置$ZTRAP选项;它不是位置的一部分。因此,在$ZTRAP上执行WRITEZZDUMP时不会显示此星号。

    ^%ETN

    在例程中,set $ZTRAP=“^%ETN”将系统提供的错误例程%ETN建立为当前错误捕获处理程序。%ETN在调用它的发生错误的上下文中执行。(%et%etn的旧名称。它们的功能相同,但%ETN的效率略高一些。)。^%ETN错误处理程序的行为总是前缀星号(*)。

    因为过程块中的$ZTRAP不能用于转到过程主体之外的位置,所以不能在过程中使用SET $ZTRAP=“^%ETN”。尝试这样做会导致<SYNTAX>错误。

    TRY / CATCH 与 $ZTRAP

    不能在TRY块内设置$ZTRAP。尝试这样做会生成编译错误。可以在TRY块之前或在CATCH块内设置$ZTRAP

    无论之前是否设置了$ZTRAPTRY块中发生的错误都由CATCH块处理。CATCH块内发生的错误由当前错误捕获处理程序处理。

    下面的第一个示例显示了TRY块中发生的错误。下面的第二个示例显示了try块中引发的异常。在这两种情况下,都会采用CATCH块,而不是$ZTRAP

    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP()
    ClassMethod ZTRAP()
    {
        SET $ZTRAP="Ztrap"
        TRY { WRITE 1/0 }    /* divide-by-zero error */
        CATCH { WRITE "Catch taken" }
        QUIT
    Ztrap
        WRITE "$ZTRAP taken"
        SET $ZTRAP=""
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTRAP()
    Catch taken
    
    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP1()
    ClassMethod ZTRAP1()
    {
        SET $ZTRAP="Ztrap"
        TRY { 
            SET myvar=##class(Sample.MyException).%New("Example Error",999,,errdatazero)
            WRITE !,"Throwing an exception!",!
            THROW myvar
            QUIT  
        } CATCH { 
            WRITE "Catch taken" 
        }
        QUIT
    Ztrap
        WRITE "$ZTRAP taken"
        SET $ZTRAP=""
        QUIT
    }
    
    
    DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTRAP1()
    Catch taken
    

    但是,try块可以调用设置和使用$ZTRAP的代码。在下面的示例中,$ZTRAP而不是CATCH块捕获被零除错误:

    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP2()
    ClassMethod ZTRAP2()
    {
        TRY { DO Errsub } 
        CATCH { WRITE "Catch taken" }
        QUIT
    Errsub
        SET $ZTRAP="Ztrap"
        WRITE 1/0   /* divide-by-zero error */
        QUIT
    Ztrap
        WRITE "$ZTRAP taken"
        SET $ZTRAP=""
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTRAP2()
    $ZTRAP taken
    

    CATCH块中的Throw命令还可以调用$ZTRAP错误处理程序。

    示例

    下面的示例将$ZTRAP设置为此程序中的OnError例程。然后,它调用发生错误的Suba(尝试将数字除以0)。当错误发生时,InterSystems IRIS调用$ZTRAP中指定的OnError例程。OnError在设置$ZTRAP的上下文级别调用。因为OnErrorMain处于相同的上下文级别,所以执行不会返回Main

    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP3()
    ClassMethod ZTRAP3()
    {
    Main
        NEW $ESTACK
        SET $ZTRAP="OnError"
        WRITE !,"$ZTRAP set to: ",$ZTRAP
        WRITE !,"Main $ESTACK= ",$ESTACK   // 0
        WRITE !,"Main $ECODE= ",$ECODE
        DO SubA
        WRITE !,"Returned from SubA"   // not executed
        WRITE !,"MainReturn $ECODE= ",$ECODE
        QUIT
    SubA
        WRITE !,"SubA $ESTACK= ",$ESTACK   // 1
        WRITE !,6/0    // Error: division by zero
        WRITE !,"fine with me"
        QUIT
    OnError
        WRITE !,"OnError $ESTACK= ",$ESTACK   // 0
        WRITE !,"$ECODE= ",$ECODE
        QUIT
    }
    
    DHC-APP>d ##class(PHA.TEST.SpecialVariables).ZTRAP3()
     
    $ZTRAP set to: +970^PHA.TEST.SpecialVariables.1
    Main $ESTACK= 0
    Main $ECODE= ,ZSYNTAX,ZSYNTAX,ZSYNTAX,ZMETHOD DOES NOT EXIST,M9,M6,M9,
    SubA $ESTACK= 1
     
    OnError $ESTACK= 0
    $ECODE= ,ZSYNTAX,ZSYNTAX,ZSYNTAX,ZMETHOD DOES NOT EXIST,M9,M6,M9,M9,
    

    下面的示例与前面的示例相同,但有一个例外:$ZTRAP位置前面有一个星号(*)。当错误发生在SUBA中时,此星号会导致InterSystems IRIS在SUBA(发生错误的地方)的上下文级调用OnError例程,而不是在Main(设置$ZTRAP的地方)的上下文级调用OnError例程。因此,当OnError完成时,执行将在do命令之后的行返回到Main

    
    /// d ##class(PHA.TEST.SpecialVariables).ZTRAP4()
    ClassMethod ZTRAP4()
    {
    Main
        NEW $ESTACK
        SET $ZTRAP="*OnError"
        WRITE !,"$ZTRAP set to: ",$ZTRAP
        WRITE !,"Main $ESTACK= ",$ESTACK   // 0
        WRITE !,"Main $ECODE= ",$ECODE
        DO SubA
        WRITE !,"Returned from SubA"   // executed
        WRITE !,"MainReturn $ECODE= ",$ECODE
        QUIT
    SubA
        WRITE !,"SubA $ESTACK= ",$ESTACK   // 1
        WRITE !,6/0    // Error: division by zero
        WRITE !,"fine with me"
        QUIT
    OnError
        WRITE !,"OnError $ESTACK= ",$ESTACK   // 1
        WRITE !,"$ECODE= ",$ECODE
        QUIT
    }
    

    相关文章

      网友评论

          本文标题:第四十四章 Caché 变量大全 $ZTRAP 变量

          本文链接:https://www.haomeiwen.com/subject/dhglfltx.html