在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"处理"错误后才能访问调用堆栈.