2013-06-02 108 views
3

在我的webapp中調用R函數時,我想在發生錯誤時捕獲堆棧跟蹤並將其呈現給用戶以進行調試。類似於交互式會話中的輸出traceback()。然而,traceback似乎並不被調用時的錯誤處理程序內的工作,它返回No traceback available使用tryCatch保存回溯錯誤使用tryCatch

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

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

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

有什麼辦法,我可以編程捕獲錯誤的堆棧跟蹤?即出現錯誤後手動調用traceback()時,我會得到的輸出:

f() 
traceback() 

回答

4

事實證明,evaluate包的最新版本具有稱爲try_capture_stack的功能,這是一個漂亮的good implementation

+2

使用.try_quietly有什麼不好的副作用? –

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

然而,錯誤和警告印刷使用sink()outConn來 - 這意味着您不能直接將結果分配給對象。要解決此問題,您可能必須更改代碼才能使用print()而不是sink未嘗試)。

+0

我發現這一個爲好,但它有許多討厭的副作用和對'tryCatch'等玩不好。 – Jeroen

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

+0

雖然這可能在理論上回答這個問題,但[這將是更可取的](// meta.stackoverflow.com/q/8259)在這裏包含了對這個特定問題的答案的基本部分,並提供了供參考的鏈接。這也適用於您最近添加的其他答案。 –

+0

好點,editet我的答案。 –