在我的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()
答案 0 :(得分:4)
事实证明,evaluate
软件包的最新版本有一个名为try_capture_stack
的函数,该函数非常good implementation。
答案 1 :(得分: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
(未尝试)。
答案 2 :(得分:1)
我没有获得与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