R 中条件对象的处理

Handling of condition objects in R

究竟发生了什么
tryCatch(warning("W"),warning = function(c) cat(c$message))

据我所知,调用 warning("W") 创建了一个类型为 warning 的条件对象 c,然后有人(谁?)寻找处理程序(在哪里?并识别处理程序如何?)并在 c.

上调用处理程序

tryCatch 的任务只是 "establish" 处理人员。这是什么意思?简而言之,问题是:条件对象究竟是如何到达其处理程序的?

根据我的经验,tryCatch 用于捕获并忽略或专门处理错误和警告。虽然您可以使用此函数执行 warnings,但我发现它更常与 withCallingHandlers(和 invokeRestart("muffleWarning"))一起使用。

Advanced R 这本书是很多主题的很好的参考;为此,我推荐两章:

  • Exceptions and debugging,哈德利强调了一个关键区别:

    withCallingHandlers() is a variant of tryCatch() that establishes local handlers, whereas tryCatch() registers exiting handlers. Local handlers are called in the same context as where the condition is signalled, without interrupting the execution of the function. When a exiting handler from tryCatch() is called, the execution of the function is interrupted and the handler is called. withCallingHandlers() is rarely needed, but is useful to be aware of.

    粗体 强调是我的,强调 tryCatch 中断, withCallingHandlers 没有。这意味着当发出警告时,不会执行任何其他操作:

    tryCatch({warning("foo");message("bar");}, warning=function(w) conditionMessage(w))
    # [1] "foo"
    tryCatch({warning("foo");message("bar");})
    # Warning in tryCatchList(expr, classes, parentenv, handlers) : foo
    # bar
    
  • 进一步 details/examples 在 Beyond exception handling 章节中。

tryCatch 在上下文中执行表达式,其中任何内容 "raised" 都可以被选择性地捕获并可能被更改、忽略、记录等。我看到的一种常见方法是接受任何错误和 return 一个已知实体(现在没有错误),例如

ret <- tryCatch(
  something_that_fails(),
  error = function(e) FALSE)

与其他允许对要处理的内容进行精确过滤的操作系统不同(例如,python 及其 try: ... except ValueError: 语法,参考:https://docs.python.org/3/tutorial/errors.html#handling-exceptions),R 在这方面有点粗糙它会捕获所有错误,您可以弄清楚它是什么类型的错误。

如果您查看 tryCatch 的源代码并跟踪它对自定义函数的使用,您会发现它最终调用了一个包含以下列表的 R 函数 .addCondHands处理程序,匹配处理程序的名称(通常是 errorwarning,但也许可以使用其他名称?)。 (可以找到该函数的源代码 here,但我发现它在这种情况下不是很有用)。

我不知道如何回答"how exactly ... get to its handler",除了抛出异常,捕获异常,并使用错误对象执行处理程序作为论据。