在遇到某种情况(比如simpleError
)时,如何调用相应的重启处理程序,系统地测试一系列实际的处理程序函数,直到发现一个不会导致另一个条件?如果已尝试最后一个可用的处理程序,则应调用默认的abortion重新启动处理程序(invokeRestart("abort")
)。实现应允许灵活地指定要使用的实际“处理程序套件”。
我不明白a)如何在重启处理程序旁边指定的 test 函数和b)使用它有意义的地方。有什么建议?一个简短的例子就是伟大的!
withRestarts
的帮助页面说:
最灵活的重启规范形式是一个列表,可以包含多个字段,包括处理程序,描述和测试。测试字段应包含一个参数的函数,一个条件,如果重新启动适用于条件,则返回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
我也有兴趣听取如何用tryCatch
部分替换withCallingHandlers
部分。好像withCallingHandlers()
似乎没有真正返回任何可以用来确定do.continue