如何在 Intersystems Caché 中使用 $etrap 真正捕获所有错误?
为此,我经常碰头。 按照 $etrap(错误处理特殊变量)的构想,您必须小心地真正捕获所有错误。 我在这方面取得了部分成功。 但我仍然缺少一些东西,因为当在用户模式(应用程序模式)下运行时,存在仍然会停止应用程序的内部缓存库错误。
我所做的是:
ProcessX(var)
set sc=$$ProcessXProtected(var)
w !,"after routine call"
quit sc
ProcessXProtected(var)
new $etrap
;This stops Cache from processing the error before this context. Code
; will resume at the line [w !,"after routine call"] above
set $etrap="set $ECODE = """" quit:$quit 0 quit"
set sc=1
set sc=$$ProcessHelper(var)
quit sc
ProcessHelper(var)
new $etrap
; this code tells Cache to keep unwindind error handling context up
; to the previous error handling.
set $etrap="quit:$quit 0 quit"
do AnyStuff^Anyplace(var)
quit 1
AnyStuffFoo(var)
; Call anything, which might in turn call many sub routines
; The important point is that we don't know how many contexts
; will be created from now on. So we must trap all errors, in any
; case.
;Call internal Cache library
quit
完成这一切之后,我可以看到当我从提示符中调用该程序时,它可以工作! 但是,当我从缓存终端脚本(我被告知应用程序模式)调用时,它会失败并中止程序(错误捕获机制无法按预期工作)。
I've been banging my head a lot because of this. In the way that $etrap (error handling special variable) was conceived you must be careful to really trap all errors. I've been partially successful in doing this. But I'm still missing something, because when run in user mode (application mode) there are internal Cache library errors that are still halting the application.
What I did was:
ProcessX(var)
set sc=$ProcessXProtected(var)
w !,"after routine call"
quit sc
ProcessXProtected(var)
new $etrap
;This stops Cache from processing the error before this context. Code
; will resume at the line [w !,"after routine call"] above
set $etrap="set $ECODE = """" quit:$quit 0 quit"
set sc=1
set sc=$ProcessHelper(var)
quit sc
ProcessHelper(var)
new $etrap
; this code tells Cache to keep unwindind error handling context up
; to the previous error handling.
set $etrap="quit:$quit 0 quit"
do AnyStuff^Anyplace(var)
quit 1
AnyStuffFoo(var)
; Call anything, which might in turn call many sub routines
; The important point is that we don't know how many contexts
; will be created from now on. So we must trap all errors, in any
; case.
;Call internal Cache library
quit
After all this, I can see that when I call the program from a prompt it works! But when I call from Cache Terminal Script (application mode, I was told) it fails and aborts the program (the error trapping mechanism doesn't work as expected).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是否有可能仅在用户模式下设置旧式错误陷阱($ZTRAP)?
关于这方面的文档非常好,所以我不会在这里重复,但关键的一点是 $ZTRAP 并不像 $ETRAP 那样是新的。 在某种程度上,它是“隐式新建的”,因为它的值仅适用于当前堆栈级别和后续调用。 一旦你退出超过它设置的级别,它就会恢复到任何以前的值。
另外,我不确定 $ETRAP 和 $ZTRAP 处理程序之间是否有定义的优先顺序,但如果 $ZTRAP 具有更高的优先级,那么将覆盖您的 $ETRAP。
您可以尝试在调用库函数之前自行设置 $ZTRAP 。 将其设置为与 $ETRAP 不同的值,这样您就可以确定触发了哪一个。
但即便如此也可能无济于事。 如果在库函数中设置 $ZTRAP,则新值将生效,因此这不会产生任何影响。 仅当 $ZTRAP 的值来自堆栈上方的某个位置时,这才会对您有帮助。
你没有提到是什么库函数导致了这个。 我的公司有一些库函数的源代码,所以如果你能告诉我函数名称,我会看看能找到什么。 请也给我 $ZVersion 的值,以便我可以确定我们正在谈论相同版本的缓存。
Is is possible that an old-style error trap ($ZTRAP) is being set only in Usermode?
The documentation on this is pretty good, so I won't repeat it all here, but a key point is that $ZTRAP isn't New-ed in the same way as $ETRAP. In a way, it is "implicitly new-ed", in that its value only applies to the current stack level and subsequent calls. It reverts to any previous value once you Quit up past the level it was set in.
Also, I'm not sure if there's a defined order of precedence between $ETRAP and $ZTRAP handlers, but if $ZTRAP is of higher precedence, that would override your $ETRAPs.
You could try setting $ZTRAP yourself right before you call the library function. Set it to something different than $ETRAP so you can be sure which one was triggered.
Even that might not help though. If $ZTRAP is being set within the library function, the new value will be in effect, so this won't make a difference. This would only help you if the value of $ZTRAP came from somewhere further up the stack.
You didn't mention what library function caused this. My company has source code for some library functions, so if you can tell me the function name I'll see what I can find. Please give me the value of $ZVersion too so I can be sure we're talking about the same version of Cache.