是否有一个 bgerror 挂钩等效于 TCL 事件循环中未捕获的错误?

Is there a bgerror hook equivalent for uncaught errors out of the event loop in TCL?

在Tcl中,当事件循环在后台发生未捕获的错误时,如果函数bgerror存在(或通过interp bgerror注册的任何函数)将被调用。

当遇到未知命令时,将调用unknown命令。

在事件循环之外是否有类似的机制来处理到达顶层的未捕获错误? tclsh 的默认行为只是打印stderr 上的错误,但我希望调用特定的 proc 而不必将整个代码放在一个大的 catch.

如果 Tcl 错误到达主执行路径的顶部,默认行为是将 errorInfo 跟踪打印到标准错误,如果 运行 作为脚本,以非零结果代码退出。如果你想覆盖它,你需要在 C 中编写你自己的条目 code/main 循环(当你可以在 Tcl_Eval() returns TCL_ERROR 时做任何你想做的事情),或者将您的代码包装在 catchtry 中。您可以在此类 Tcl 代码中使用 uplevel #0 以确保捕获代码不会像您的其余代码所看到的那样出现在堆栈上。

例如:

proc printStackOnError {script} {
    try {
        uplevel "#0" $script
    } on error {msg opt} {
        set stackinfo [dict get $opt -errorinfo]
        # remove last three uninteresting lines; they're just part of this procedure's machinery
        puts stderr [join [lrange [split $stackinfo "\n"] 0 end-3] "\n"]
    }
}

演示(交互式,使用 Tcl 8.6):

% printStackOnError {eval {error foo}}
foo
    while executing
"error foo"
    ("eval" body line 1)
    invoked from within
"eval {error foo}"

当在该级别捕获错误时,建议您确保打印或记录 errorInfo。否则代码中的任何错误都将难以修复。