【问题标题】:`withCallingHandlers` inside `tryCatch` creates uncatchable error`tryCatch` 中的 `withCallingHandlers` 会产生无法捕获的错误
【发布时间】:2017-07-19 07:22:05
【问题描述】:

我需要将警告转换为错误,以便能够在上游进一步处理它(警告被吞没在中间的某个地方,我无法控制;错误不是)。为此,我正在执行以下操作:

warning_to_error = function (expr)
    withCallingHandlers(expr, warning = stop)

这很好用:

> warning_to_error(warning('foobar'))
Error in withCallingHandlers(expr, warning = stop) : foobar

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

> try(warning_to_error(warning('foobar')))
Error in withCallingHandlers(expr, warning = stop) : foobar

In my real situation,在我的warning_to_errortry 之间有好几层(包括消除警告的逻辑)。如何使调用处理程序引发的错误可捕获?不幸的是,我不能像in another Stack Overflow question 所述使用重启,因为stop 没有定义重启,而且我再次无法控制执行捕获的代码。

【问题讨论】:

    标签: r error-handling


    【解决方案1】:

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

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

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

    warning_to_error1 <- function (expr)
        withCallingHandlers(expr,
                            warning = function(w)
                                stop("(converted from warning) ",
                                     conditionMessage(w)))
    

    这给了你

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

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

    【讨论】:

    • 谢谢,这很有意义。我实际上试图这样做(= 打印/返回条件以检查它)但我的尝试失败了,因为我根本没有想到这个类将是 error 以外的任何东西。呵呵。
    • 如果我能以某种方式欺骗调用堆栈信息,那就更好了。不幸的是,即使使用eval,在warning_to_errorparent.frame() 中执行,我也无法实现这一点:堆栈跟踪总是以eval 本身结束。我猜这是不可能的?
    • 创建一个错误条件对象并将sys.calls的结果存储在其中,然后将其传递给stop
    • 太棒了。这只修复了显示,而不是实际的堆栈跟踪,但我可以忍受(无论如何这可以说是想要的结果)。
    猜你喜欢
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    相关资源
    最近更新 更多