注:该文档代码均来自Ensemble官方文档
异常处理机制和大部分语言都一样,使用try将会抛出异常的语句包起来,在catch中处理异常,也可以用throw直接将异常抛出,交给父catch去处理看个简单的例子
TRY { SET total=1234 WRITE !,"Throw an exception!" THROW ##class(Sample.MyException).%New("Example Error",45) WRITE !,"this should not display" } CATCH myvar { WRITE !,"this is the exception handler" WRITE !,"Error code=",myvar.Code WRITE !,"Error name=",myvar.Name } WRITE !,"this is where the code falls through"
try块中 Sample.MyException类本身不存在,所以在new的时候会抛出异常,该类不存在,在catch中对异常进行说明,取到异常代码,和异常说明,继续执行后续语句,值得说明的就是,在抛出异常后我们后面的语句会继续执行,只是在执行的时候一旦遇到向之前类似的引用,程序将会报错。
在ensemble/cache中没有finally关键字
再看一段正常处理异常的例子,不影响后续代码的执行
TRY{
KILLx
WRITE!,"x is an undefined variable"
SETa=x
}
CATCHexceptionvar
{
WRITE!,"this is the error routine"
sx=1
WRITE!,"the error was: ",$ZERROR
WRITE!,"the error was: ",$ECODE
}
w!,x
WRITE!,"this is where the code falls through"
WRITE!,"the error was: ",$ZERROR
WRITE!,"the error was: ",$ECODE
在本段代码中,x不存在,所以在set a=x时会抛出异常,x未定义,所以我们在catch中设置x的值,这样在后续使用中就不会报错。
再看一段使用throw抛出异常的例子
TRY { SET errdatazero="this is the zero error" SET errdataone="this is the one error" /* Error Randomizer */ SET test=$RANDOM(3) WRITE "Error test is ",test,! IF test=0 { SET myvar=##class(Sample.MyException).%New("Example Error",999,,errdatazero) WRITE !,"Throwing an exception!",! THROW myvar } ELSEIF test=1 { SET myvar=##class(Sample.MyException).%New("Example Error",999,,errdataone) WRITE !,"Throwing an exception!",! THROW myvar } ELSE { WRITE !,"No THROW error this time" } } CATCH { WRITE !,"This is the exception handler" WRITE !,"Error code=",myvar.Code WRITE !,"Error name=",myvar.Name WRITE !,"Error data=",myvar.Data QUIT } WRITE !,!,"NOTE: Execution continues here"