【问题标题】:Calling stop( ) within function causes R CMD Check to throw error在函数内调用 stop() 会导致 R CMD Check 抛出错误
【发布时间】:2020-12-03 09:19:11
【问题描述】:

我正在尝试从内部包函数 (stop_quietly()) 中调用 stop(),它应该会中断该函数并返回到顶部。这可行,除了 R CMD Check 认为这是一个错误,因为我正在强制停止。

如何绕过 R CMD 检查将此解释为错误?该函数需要停止,因为它需要用户输入作为确认,然后才能在给定位置创建文件目录树。该代码当前生成一条消息并停止该函数。

tryCatch({
      path=normalizePath(path=where, winslash = "\\", mustWork = TRUE)
      message(paste0("This will create research directories in the following directory: \n",path))
      confirm=readline(prompt="Please confirm [y/n]:")
      if(tolower(stringr::str_trim(confirm)) %in% c("y","yes","yes.","yes!","yes?")){
         .....
         dir.create(path, ... [directories])
         .....
       }
       message("There, I did some work, now you do some work.")
      }
        else{
        message("Okay, fine then. Don't do your research. See if I care.")
        stop_quietly()
      }
    },error=function(e){message("This path does not work, please enter an appropriate path \n or set the working directory with setwd() and null the where parameter.")})

stop_quietly 是一个退出函数I took from this post,修改了error=NULL,它抑制了R 作为浏览器执行错误处理程序。我不希望函数终止到浏览器我只是希望它退出而不在 R CMD 检查中引发错误。

stop_quietly <- function() {
  opt <- options(show.error.messages = FALSE, error=NULL)
  on.exit(options(opt))
  stop()
}

这是 R CMD 产生的错误的组成部分:

-- R CMD check results ------------------------------------------------ ResearchDirectoR 1.0.0 ----
Duration: 12.6s

> checking examples ... ERROR
  Running examples in 'ResearchDirectoR-Ex.R' failed
  The error most likely occurred in:
  
  > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
  > ### Name: create_directories
  > ### Title: Creates research directories
  > ### Aliases: create_directories
  > 
  > ### ** Examples
  > 
  > create_directories()
  This will create research directories in your current working directory: 
  C:/Users/Karnner/AppData/Local/Temp/RtmpUfqXvY/ResearchDirectoR.Rcheck
  Please confirm [y/n]:
  Okay, fine then. Don't do your research. See if I care.
  Execution halted

【问题讨论】:

  • 出于好奇,R CMD check 产生的确切错误消息是什么? (这可能与问题无关,但听起来很奇怪。)
  • @KonradRudolph:我猜想stop() 的调用发生在一个例子中。示例不允许产生错误,除非您将它们包装在 tryCatch() 或等效项中。
  • @KonradRudolph 它是由一个例子抛出的,所以我想知道如何将它包装在 tryCatch() 中而不将其称为错误......因为它本身不是错误。错误添加到原始帖子。
  • @JonathanFluharty-J​​aidee Ha,好的,知道了。显然R CMD check itself 依赖于已安装的错误处理程序,因此如果禁用它,它将失败。您需要确保 R CMD check 不会最终执行该特定代码(例如,通过示例,如您的情况,或在小插图中)。要解决此问题,只需将示例代码包装在 \donotrun{…} 中。

标签: r namespaces exit


【解决方案1】:

由于您的函数具有全局副作用,我认为check 不会喜欢它。如果您要求用户将tryCatch 放在顶层,然后让它捕获错误,情况会有所不同。但是考虑一下这种情况:用户定义f() 并调用它:

f <- function() {
  call_your_function()
  do_something_essential()
}
f()

如果您的函数静默导致它跳过f() 的第二行,可能会给用户带来很多麻烦。

你可以做的是告诉用户将你的函数调用包装在tryCatch()中,并让它捕获错误:

f <- function() {
  tryCatch(call_your_function(), error = function(e) ...)
  do_something_essential()
}
f()

这样用户就会知道你的函数失败了,并且可以决定是否继续。

从 cmets 中的讨论和您对问题的编辑来看,您的功能似乎只打算以交互方式使用,因此上述情况不是问题。在这种情况下,您可以通过跳过示例来避免R CMD check 问题,除非它是交互式运行的。这相当简单:在像create_directories() 这样的函数的帮助页面中,将您的示例设置为

if (interactive()) {
  create_directories()
  # other stuff if you want
}

检查运行时interactive() 返回FALSE,因此这将阻止检查中发生错误。你也可以在create_directories() 中使用tryCatch 来捕捉来自下方的错误,如果这在你的包中更有意义的话。

【讨论】:

  • 我可能误解了你,但是 stop_silently( ) 是包内部的,所以用户不应该访问它。主要功能生成我用于研究的常用文件夹的目录树,并创建预模板化的 .Rnw 文件以加快研究项目的启动。 stop_silently() 是一个故障保护,程序要求用户确认放置目录树的位置。他们用 [y/n] 确认,“n”输入应该生成一条消息,即(“好的,我不会那样做。”)然后终止函数。还有其他错误处理程序包装我需要跳过。更新了主帖。
  • 您的示例调用create_directories(),然后它会爆炸。如果在我的示例中由call_your_function() 调用,则永远不会调用do_something_essential(),并且用户不会收到错误消息(因为您将其静音)。如果您希望它完全是内部的,那么将您自己的代码放在tryCatch() 中。如果create_directories()只是为了交互调用,那么把例子放到if (interactive()) ...里面就不会在R CMD check里面调用了。
  • 我想我理解您的担忧是用户在他们自己的代码中使用我的函数也会终止他们创建的任何函数。这确实是一个问题。我想我会走互动路线。您能否更新您的原始答案,以便我给予积分?
  • 我已经更改了最后一部分。
猜你喜欢
  • 1970-01-01
  • 2021-05-13
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
相关资源
最近更新 更多