4

在我的 webapp 中调用 R 函数时,我想在发生错误时捕获堆栈跟踪并将其呈现给用户以进行调试。类似于traceback()交互式会话中的输出。但是,traceback在错误处理程序中调用它时似乎不起作用,它返回No traceback available

f <- function() {
    g <- function() stop("test traceback")
    g()
}

errhandler <- function(e){
  stacktrace <- traceback()
  unlist(stacktrace);
}

out <- tryCatch(f(), error=errhandler) 

有什么方法可以以编程方式捕获错误的堆栈跟踪?traceback()即得到错误后手动调用时我会得到的输出:

f()
traceback()
4

3 回答 3

4

事实证明,最新版本的evaluate包有一个名为的函数try_capture_stack,这是一个很好的实现

于 2013-06-02T23:50:12.490 回答
2

该函数tools:::.try_quietly执行类似的操作:

f <- function() {
  g <- function() stop("test traceback")
  g()
}

tools:::.try_quietly(f()) 

Error: test traceback
Call sequence:
3: stop("test traceback")
2: g()
1: f()

但是,错误和警告会打印到outConn使用sink()- 这意味着您不能直接将结果分配给对象。要解决此问题,您可能必须更改要使用的代码,print()而不是sink( untried )。

于 2013-06-02T06:00:25.017 回答
1

我没有像使用 traceback 那样获得堆栈try_capture_stack,所以我编写了一个类似于 的解决方案try,除了它还返回调用堆栈。tools:::.try_quietly很整洁,但不保存堆栈供以后检查...

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])

我的答案中的更多信息: https ://stackoverflow.com/a/40899766/1587132

于 2016-11-30T23:02:18.500 回答