2013-06-02 2 views
3

웹 응용 프로그램 내에서 R 함수를 호출 할 때 오류가 발생하면 스택 추적을 catch하여 디버깅 목적으로 사용자에게 제시하고 싶습니다. 대화 형 세션에서 traceback()의 출력과 같은 것입니다. 그러나 traceback 그것이 오류 처리기 내에서 호출 할 때 작동하지 않는 것, 그것은 No traceback available 반환 : 나는 프로그램 적 오류의 스택 추적을 잡을 수있는 방법이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 패키지의 최신 버전은이 중 good implementationtry_capture_stack이라는 기능이 있습니다.

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

그러나, 오류 및 경고가 outConnsink()를 사용하여 인쇄를 -이 결과를 객체에 직접 할당 할 수 없음을 의미합니다. 이 문제를 해결하려면 코드를 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

좋은 지적, 편집 내 대답. –