20

これは他のいくつかの質問に関連していますが、答えを適用する方法がわからないようなので、新しい質問をしています。

次のようなコードから、有益でないエラーを見つけようとしています。

tryCatch(MainLoop(), 
  error=function(e) { fatal(lgr, paste('caught fatal error:', as.character(e))); 
                      exit.status <<- 1 })

問題は、エラーがライブラリ関数に埋め込まれている何かに関連しているように見えることです:

Error in nrow(x): (subscript) logical subscript too long

上記の C レベルのエラーは、どの呼び出しでも発生しないタイプのインデックス作成にのみ適用されるため、これnrowは私のコードにはありません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"

への呼び出しを含むスタック トレースを取得するにはどうすればよいy()ですか? 使用を中止する必要がありtryCatchますか? より良い方法は何ですか?

4

4 に答える 4

19

対話的に使用するために、呼び出さtrace(stop, quote(print(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...

それで

>     withCallingHandlers(x(), error=function(e) print(sys.calls()))
[[1]]
withCallingHandlers(x(), error = function(e) print(sys.calls()))

[[2]]
x()

[[3]]
y()

[[4]]
z()

[[5]]
stop("asdf")

[[6]]
.handleSimpleError(function (e) 
print(sys.calls()), "asdf", quote(z()))

[[7]]
h(simpleError(msg, call))

Error in z() : asdf

内部の tryCatch がある場合、これは妨げられます

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

tryCatch がエラーを「処理」した後にのみコール スタックにアクセスできるためです。

于 2013-03-07T23:27:30.783 に答える
3

はい、可能です。コーディングはあまりエレガントではありませんが、出力には非常に役立ちます! どんなコメントでも大歓迎です!

ドキュメントが必要な場合は、そこから使用してください。 https://github.com/brry/berryFunctions/blob/master/R/tryStack.R 次の 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])

d <- tryStack(upper("4"))

これはエラー スタックです。

tryStack(upper("4"))

上("4")

下(b)

+ 10 のエラー: 二項演算子への数値以外の引数

于 2016-11-30T22:54:31.577 に答える