另一个后续行动this https://stackoverflow.com/questions/15295004/disregarding-simple-warnings-errors-in-trycatch?noredirect=1#comment21587644_15295004 and this https://stackoverflow.com/questions/15363004/advanced-condition-handling.
实际问题
问题1
当遇到某种情况时(比如simpleError
),如何调用相应的重新启动处理程序来系统地测试一系列实际处理程序函数,直到发现一个不会导致另一种情况?如果已尝试最后一个可用的处理程序,则应调用默认的中止重新启动处理程序(invokeRestart("abort")
)。该实现应该允许对要使用的实际“处理程序套件”进行灵活的规范。
问题2
我不明白如何a)atest与重新启动处理程序一起指定的函数可以工作,并且 b) 在有意义的地方使用它。有什么建议么?一个简短的例子就太好了!
的帮助页面withRestarts
says:
重新启动规范最灵活的形式是作为一个列表,其中可以包含多个字段,包括处理程序、描述和测试。测试字段应包含一个只有一个参数的函数,即一个条件,如果重新启动适用于该条件,则返回 TRUE;如果不适用,则返回 FALSE;默认函数在所有条件下都返回 TRUE。
对于那些有兴趣了解更多细节的人
下面您将找到我针对问题 1 的第一种方法,但我确信还有更清晰/更直接的方法;-)
foo <- function(x, y) x + y
fooHandled <- function(
x,
y,
warning=function(cond, ...) {
invokeRestart("warninghandler", cond=cond, ...)},
error=function(
cond,
handlers=list(
expr=expression(x+"b"),
expr=expression(x+"c"),
expr=expression(x+100)
),
...) {
invokeRestart("errorhandler", cond=cond, handlers=handlers, ...)
}
) {
expr <- expression(foo(x=x, y=y))
withRestarts(
withCallingHandlers(
expr=eval(expr),
warning=warning,
error=error
),
warninghandler=function(cond, ...) warning(cond),
errorhandler=function(cond, handlers, ...) {
idx <- 1
do.continue <- TRUE
while (do.continue) {
message(paste("handler:", idx))
expr <- handlers[[idx]]
out <- withRestarts(
tryCatch(
expr=eval(expr),
error=function(cond, ...) {
print(cond)
message("trying next handler ...")
return(cond)
}
)
)
idx <- idx + 1
do.continue <- inherits(out, "simpleError")
}
return(out)
}
)
}
> fooHandled(x=1, y=1)
[1] 2
> fooHandled(x=1, y="a")
handler: 1
<simpleError in x + "b": non-numeric argument to binary operator>
trying next handler ...
handler: 2
<simpleError in x + "c": non-numeric argument to binary operator>
trying next handler ...
handler: 3
[1] 101
EDIT
我也有兴趣听听如何替代tryCatch
部分与withCallingHandlers
部分。似乎withCallingHandlers()
并没有真正返回任何可以用来确定值的东西do.continue