我将使用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
出了什么问题?
答案 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
表达式在退出当前函数时运行,因此需要在函数内运行。如果您正在编写的代码已经在函数中,那么您不需要使用此包装器。