在R中的tryCatch'ed错误上获取堆栈跟踪

Har*_*lan 18 error-handling r

这与其他一些问题有关,但我似乎无法弄清楚如何应用答案,所以我问了一个新问题.

我试图从一段看起来像这样的代码中找出一个无法解释的错误:

tryCatch(MainLoop(), 
  error=function(e) { fatal(lgr, paste('caught fatal error:', as.character(e))); 
                      exit.status <<- 1 })
Run Code Online (Sandbox Code Playgroud)

问题是该错误似乎与库函数中隐藏的内容有关:

Error in nrow(x): (subscript) logical subscript too long
Run Code Online (Sandbox Code Playgroud)

这nrow不在我的代码中,因为上面的C级错误仅适用于我的任何nrow调用中从未发生过的索引类型.

所以我真的想从内部得到一个堆栈跟踪tryCatch.这是一个类似的问题:

x <- function() { y(); }
y <- function() { z(); }
z <- function() { stop("asdf") }

> x()
Error in z() : asdf
> tryCatch(x(), error=function(e) { print(conditionCall(e)) } )
z()
> tryCatch(x(), error=function(e) { dump.frames() } )
> last.dump
$`tryCatch(x(), error = function(e) {
    dump.frames()
})`
<environment: 0x1038e43b8>

$`tryCatchList(expr, classes, parentenv, handlers)`
<environment: 0x1038e4c60>

$`tryCatchOne(expr, names, parentenv, handlers[[1]])`
<environment: 0x1038e4918>

$`value[[3]](cond)`
<environment: 0x1038ea578>

attr(,"error.message")
[1] "asdf"
attr(,"class")
[1] "dump.frames"
Run Code Online (Sandbox Code Playgroud)

如何获得包含调用的堆栈跟踪y()?我必须停止使用tryCatch吗?什么是更好的方式?

Mar*_*gan 17

对于交互式使用,可以trace(stop, quote(print(sys.calls())))在调用时打印调用堆栈stop().

来自?tryCatch,

 The function 'tryCatch' evaluates its expression argument in a
 context where the handlers provided in the '...'  argument are
 available.
Run Code Online (Sandbox Code Playgroud)

而

 Calling handlers are established by 'withCallingHandlers'...
 the handler is called... in the context where the condition
 was signaled...
Run Code Online (Sandbox Code Playgroud)

所以

>     withCallingHandlers(x(), error=function(e) print(sys.calls()))
[[1]]
withCallingHandlers(x(), error = function(e) print(sys.calls()))

[[2]]
x()

[[3]]
y()

[[4]]
z()

[[5]]
stop("asdf")

[[6]]
.handleSimpleError(function (e) 
print(sys.calls()), "asdf", quote(z()))

[[7]]
h(simpleError(msg, call))

Error in z() : asdf
Run Code Online (Sandbox Code Playgroud)

如果有一个内部的tryCatch,这会被挫败

withCallingHandlers({
    tryCatch(x(), error=function(e) stop("oops"))
}, error=function(e) print(sys.calls()))
Run Code Online (Sandbox Code Playgroud)

因为我们只有在tryCatch"处理"错误后才能访问调用堆栈.