2

许多 Caché API 方法返回一个 %Status 对象,该对象指示这是否是一个错误。问题是,当它是一个未知错误时,我不知道如何处理(如网络故障)我真正想做的是“抛出”错误,以便我的代码停止它正在做的事情并且错误被更高级别的级别错误处理程序(和/或内置的 %ETN 错误日志)。

我可以ztrap像这样使用:

s status = someObject.someMethod()
ztrap:$$$ISERR(status)

但这并没有报告太多细节(不像.NET,我可以一直抛出异常到堆栈顶部),我想知道是否有更好的方法来做到这一点。

4

2 回答 2

2

查看 %Exception.StatusException 的类参考。您可以从您的状态创建一个异常并将其抛出到当时处于活动状态的任何错误陷阱(因此控制流程与您的 ZTRAP 示例相同),如下所示

set sc = someobj.MethodReturningStatus()
if $$$ISERR(sc) {
   set exception = ##class(%Exception.StatusException).CreateFromStatus(sc)
   throw exception
}

但是,为了恢复捕获该异常的错误陷阱代码中的异常信息,必须使用try/catch 建立错误陷阱。较旧的错误处理程序 $ztrap 和 $etrap 不向您提供异常对象,您只会看到作为 $ZERROR 值的 <NOCATCH> 错误。即使在这种情况下,控制流也会按照你的意愿工作,但是没有 try/catch,你不会比使用 ZTRAP 更好

于 2011-10-27T21:11:22.300 回答
1

这是两种不同的错误机制,不能以这种方式组合。ztrap 和 %ETN 用于缓存级别错误(尖括号错误,如<UNDEFINED>)。%Status 对象用于应用程序级别的错误(包括通过使用缓存类库发生的错误),您可以选择自己处理它们的方式。通过 Cache 错误机制处理错误的 %Status 并没有真正的意义,因为没有发生 Cache 错误。

一般来说,大多数人所做的事情类似于:

d:$$$ISERR(状态) $$$SomeMacroRelevantToMyAppThatWillHandleThisStatus(状态)

可以使用您自己的整个 %Status 代码主机创建您自己的域,并为您的应用程序提供相应的 %msg 值。您的应用程序可能已尝试连接到 FTP 服务器并且密码错误,但这不会抛出 a<DISCONNECT>并且没有理由调查堆栈,只是需要处理的应用程序级错误,可能通过询问用户输入新密码。

存在这两种并行错误机制可能看起来很奇怪,但它们描述的是两种不同类型的错误。将其中一个视为“平台”级错误,将另一个视为“应用程序级错误”

编辑:我忘记了一件事,尝试 DecomposeStatus^%apiOBJ(status) 或 ##class(%Status).LogicalToOdbc(status) 将状态对象转换为人类可读的字符串。此外,如果您正在执行命令行调试或只想将可读表单打印到主体设备,您可以使用 $system.OBJ.DisplayError(status)。

于 2011-10-07T02:38:55.677 回答