`tryCatch`中的`withCallingHandlers`会产生无法捕获的错误

Kon*_*lph 9 error-handling r

我需要将一个警告转换为一个错误,以便能够进一步向上游处理(警告被中间某处吞没,我无法控制;错误不是).为此,我正在做以下事情:

warning_to_error = function (expr)
    withCallingHandlers(expr, warning = stop)
Run Code Online (Sandbox Code Playgroud)

这非常有效:

> warning_to_error(warning('foobar'))
Error in withCallingHandlers(expr, warning = stop) : foobar
Run Code Online (Sandbox Code Playgroud)

不幸的是,这使错误完全无法捕获:

> try(warning_to_error(warning('foobar')))
Error in withCallingHandlers(expr, warning = stop) : foobar
Run Code Online (Sandbox Code Playgroud)

在我的实际情况中,我warning_to_error和我之间有几层try(包括警告的逻辑).如何使我的调用处理程序引发的错误可以捕获?不幸的是我无法使用另一个Stack Overflow问题中描述stop的重启,因为没有定义重启,而且我再次无法控制执行捕获的代码.

Luk*_*ney 7

这应该告诉你你的定义发生了什么warning_to_error:

> tryCatch(warning_to_error(warning('foobar')), condition = print)
<simpleWarning in withCallingHandlers(expr, warning = stop): foobar>```
Run Code Online (Sandbox Code Playgroud)

正如文档所述stop,当您stop使用条件调用时,会通知该条件以查找处理程序,这意味着warning在这种情况下处理程序.如果要调用错误处理程序,则需要发出错误信号.这就是你设置options(warn = 2)的例子.所以你需要类似的东西

warning_to_error1 <- function (expr)
    withCallingHandlers(expr,
                        warning = function(w)
                            stop("(converted from warning) ",
                                 conditionMessage(w)))
Run Code Online (Sandbox Code Playgroud)

那给了你

> tryCatch(warning_to_error1(warning('foobar')),
+          error = function(e) print("Got it"))
[1] "Got it"
Run Code Online (Sandbox Code Playgroud)

理想情况下,我们应该为转换为错误的警告提供条件类和构造函数,并在内部使用它 warn = 2