如何在R中重新抛出错误?

时间:2013-12-25 07:16:52

标签: r error-handling try-catch

我将使用tryCatch捕获错误,并尝试处理错误。但是,如果我无法在本地处理错误(即委托给调用堆栈中较高位置的父函数的错误处理程序),如何重新抛出错误?

我尝试使用signalCondition,但我没有看到重新抛出的错误,而是NULL

> error.can.be.handled <- function(e) F
> 
> foo <- function() stop("foo stop!")
> tryCatch(foo(),
+   error = function(e) {
+       if (error.can.be.handled(e)) {
+           # handle error
+       }
+       else
+           signalCondition(e) # Rethrow error
+   }
+ )
NULL  # I expected to see 'Error in foo() : foo stop!' here

出了什么问题?

3 个答案:

答案 0 :(得分:10)

tryCatch(stop("oops"), error=function(e) stop(e))

将重新发出停止条件,尽管上下文已丢失

> tryCatch(stop("oops"), error=function(e) stop(e))
Error in doTryCatch(return(expr), name, parentenv, handler) : oops
> traceback()
5: stop(e)
4: value[[3L]](cond)
3: tryCatchOne(expr, names, parentenv, handlers[[1L]])
2: tryCatchList(expr, classes, parentenv, handlers)
1: tryCatch(stop("oops"), error = function(e) stop(e))
> tryCatch(stop("oops"))
Error in tryCatchList(expr, classes, parentenv, handlers) : oops
> traceback()
3: stop("oops")
2: tryCatchList(expr, classes, parentenv, handlers)
1: tryCatch(stop("oops"))

仅仅{@ 1}}返回@tonytonov建议确实表示已经发生了一个条件,但没有发生错误。

答案 1 :(得分:0)

无论如何都不需要signalCondition():

tryCatch(foo(),
    error = function(e) {
        if (error.can.be.handled(e)) {
            # handle error
        }
        else
            e # Rethrow error
    }
  )

<simpleError in foo(): foo stop!>

答案 2 :(得分:0)

您可以使用一种解决方法来避免必须捕获并重新抛出错误。基本上,只有当相关代码失败时,才使用带有on.exit处理程序的成功标志来运行代码块:

foo <- function() stop("foo stop!")
runFoo <- function() {
    success <- FALSE
    on.exit({
        if (!success) {
            ## Handle failure
        }
    })
    result <- foo()
    success <- TRUE
    result
}
runFoo()

这种方法的主要缺点是,虽然您知道发生了错误(因为success从未设置为TRUE),但您无法访问错误对象本身,因此您需要使用其他方法来检测是否可以处理错误。

需要runFoo包装函数,因为on.exit表达式在退出当前函数时运行,因此需要在函数内运行。如果您正在编写的代码已经在函数中,那么您不需要使用此包装器。