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

在tryCatch'上获取堆栈跟踪;R中的ed错误,r,error-handling,R,Error Handling,这与其他一些问题有关,但我似乎不知道如何应用答案,所以我要问一个新问题 我试图从一段代码中找出一个非信息性错误,如下所示: tryCatch(MainLoop(), error=function(e) { fatal(lgr, paste('caught fatal error:', as.character(e))); exit.status <<- 1 }) 该nrow不在我的代码中,因为上面的C级错误只适用于在我的nrow调

这与其他一些问题有关,但我似乎不知道如何应用答案,所以我要问一个新问题

我试图从一段代码中找出一个非信息性错误,如下所示:

tryCatch(MainLoop(), 
  error=function(e) { fatal(lgr, paste('caught fatal error:', as.character(e))); 
                      exit.status <<- 1 })
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"
x tryCatch(x(),error=function(e){dump.frames()})
>最后一个垃圾场
$`tryCatch(x(),error=function(e){
dump.frames()
})`
$`tryCatchList(expr、类、parentenv、处理程序)`
$`tryCatchOne(expr、name、parentenv、handlers[[1]])`
$`value[[3]](第二个)`
属性(,“error.message”)
[1] “asdf”
属性(,“类”)
[1] “转储。帧”

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

对于交互式使用,可以
跟踪(停止,引用(打印(sys.calls()))
在调用
stop()
时打印调用堆栈

?tryCatch

 The function 'tryCatch' evaluates its expression argument in a
 context where the handlers provided in the '...'  argument are
 available.
鉴于

 Calling handlers are established by 'withCallingHandlers'...
 the handler is called... in the context where the condition
 was signaled...
所以

如果存在内部tryCatch,则会阻止此操作

withCallingHandlers({
    tryCatch(x(), error=function(e) stop("oops"))
}, error=function(e) print(sys.calls()))

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

是的,这是可能的。它在编码方面不太优雅,但在输出方面非常有用! 欢迎评论

我把它放在我的misc软件包中,如果你需要文档,可以从那里使用它。 计划很快发布下一个CRAN版本,直到那时:

devtools::install_github("brry/berryFunctions")
# or use:
source("http://raw.githubusercontent.com/brry/berryFunctions/master/R/instGit.R")
instGit("brry/berryFunctions")

library(berryFunctions)
?tryStack
以下为快速参考:

tryStack <- function(
expr,
silent=FALSE
)
{
tryenv <- new.env()
out <- try(withCallingHandlers(expr, error=function(e)
  {
  stack <- sys.calls()
  stack <- stack[-(2:7)]
  stack <- head(stack, -2)
  stack <- sapply(stack, deparse)
  if(!silent && isTRUE(getOption("show.error.messages"))) 
    cat("This is the error stack: ", stack, sep="\n")
  assign("stackmsg", value=paste(stack,collapse="\n"), envir=tryenv)
  }), silent=silent)
if(inherits(out, "try-error")) out[2] <- tryenv$stackmsg
out
}

lower <- function(a) a+10
upper <- function(b) {plot(b, main=b) ; lower(b) }

d <- tryStack(upper(4))
d <- tryStack(upper("4"))
cat(d[2])

tryStack我是
evaluate::try\u capture\u stack()
的粉丝

x[[2]]
#>y()
#> 
#> [[3]]
#>z()
#> 
#> [[4]]
#>停止(“asdf”)

我参加聚会有点晚,但我发现最好的方法是在您尝试的函数中使用退出处理程序

main <- function()
{
  on.exit({
    msg <- capture.output(traceback())
    if (msg != "No traceback available ")
    {
      print(msg)
    }
  }
  )
  # rest of code
}

withCallingHandlers(
  expr =
    {
      main()
    },
  error = function(e) 
  {
    print(e)
  }
)

main那么在发生错误之后,到目前为止您尝试了哪些调试?traceback()选项(错误=恢复)?后者不会让你陷入困境吗?它应该这样做,即使在库中,直到它至少达到C代码。如果您使用的是C代码,那么您可能必须将GDB与RTIS一起用于在生产环境中运行的代码,我在开发过程中遇到了一个尚未重现的错误,因此进入恢复模式不是一个选项,不幸的是。。。我希望更好的仪器能更准确地指出错误。谢谢这是有道理的,而且似乎有效——谢谢!我已将
tryCatch
替换为
withCallingHandlers
,并在错误处理程序块中放入以下方便的表达式:
dump.frames(format(Sys.time(),format=“dump\u%Y%m%d%H%m%S”),to.file=TRUE)
。希望我现在能找出错误。。。
tryStack <- function(
expr,
silent=FALSE
)
{
tryenv <- new.env()
out <- try(withCallingHandlers(expr, error=function(e)
  {
  stack <- sys.calls()
  stack <- stack[-(2:7)]
  stack <- head(stack, -2)
  stack <- sapply(stack, deparse)
  if(!silent && isTRUE(getOption("show.error.messages"))) 
    cat("This is the error stack: ", stack, sep="\n")
  assign("stackmsg", value=paste(stack,collapse="\n"), envir=tryenv)
  }), silent=silent)
if(inherits(out, "try-error")) out[2] <- tryenv$stackmsg
out
}

lower <- function(a) a+10
upper <- function(b) {plot(b, main=b) ; lower(b) }

d <- tryStack(upper(4))
d <- tryStack(upper("4"))
cat(d[2])
x <- function() {
  y()
}
y <- function() {
  z()
}
z <- function() {
  stop("asdf")
}
env <- environment()
e <- evaluate::try_capture_stack(quote(x()), env)
names(e)
#> [1] "message" "call"    "calls"
e$calls
#> [[1]]
#> x()
#> 
#> [[2]]
#> y()
#> 
#> [[3]]
#> z()
#> 
#> [[4]]
#> stop("asdf")
main <- function()
{
  on.exit({
    msg <- capture.output(traceback())
    if (msg != "No traceback available ")
    {
      print(msg)
    }
  }
  )
  # rest of code
}

withCallingHandlers(
  expr =
    {
      main()
    },
  error = function(e) 
  {
    print(e)
  }
)