首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果通过tryCatch调用RScript,则RScript不会捕获错误

如果通过tryCatch调用RScript,则RScript不会捕获错误
EN

Stack Overflow用户
提问于 2012-07-09 10:45:29
回答 2查看 6.7K关注 0票数 15

我在R.面临一个奇怪的问题。

考虑以下代码(真实代码的一个非常简化的版本,但仍然存在问题):

代码语言:javascript
复制
library(timeSeries)

tryCatch(
{
  specificWeekDay <- 2

  currTs <- timeSeries(c(1,2),c('2012-01-01','2012-01-02'),
                       format='%Y-%m-%d',units='A')
  # just 2 dates out of range
  start <- time(currTs)[2]+100*24*3600
  end <- time(currTs)[2]+110*24*3600

  # this line returns an empty timeSeries
  currTs <- window(currTs,start=start,end=end)

  message("Up to now, everything is OK")

  # this is the line with the uncatchable error
  currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA

  message("I'm after the bugged line !")

},error=function(e){message(e)})

message("End")

当我在RGui中运行该代码时,我正确地获得了以下输出:

到现在为止,一切都很好 在为函数选择方法时计算参数'i‘时出错[<-’:as.POSIXlt.numeric中的错误(time(CurrTs)):‘原产地’必须提供 结束

相反,当我使用以下行通过RScript (在windows中)运行它时:

代码语言:javascript
复制
RScript.exe --vanilla "myscript.R"

我得到了这个输出:

到现在为止,一切都很好 执行中断

好像RScript崩溃了..。

知道原因吗?

这是timeSeries包错误,还是我做错了什么?

如果是后者,那么确保捕获所有错误的正确方法是什么?

提前谢谢。

编辑:

下面是一个不使用timeSeries包的问题的复制示例。要测试它,只需像上面描述的那样运行它:

代码语言:javascript
复制
library(methods)
# define a generic function
setGeneric("foo", 
           function(x, ...){standardGeneric("foo")})
# set a method for the generic function
setMethod("foo", signature("character"),
          function(x) {x})
tryCatch(
{
  foo("abc")
  foo(notExisting)
},error=function(e)print(e))

这似乎与泛型方法调度有关;当方法的参数导致错误时,调度程序无法找到该方法的签名,因此会引发tryCatch函数在运行RScript时似乎无法处理的异常。

奇怪的是,这种情况在print(notExisting)中没有发生;在这种情况下,异常是正确处理的。

知道原因和如何捕捉这种错误吗?

注意:

我在Windows 7上使用R-2.14.2

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-11 16:46:05

问题在于实现S4方法的内部C代码如何尝试捕捉和处理一些错误,以及在这种方法中如何处理非交互的情况。R-devel和R-修补很快就会有一个解决方案。

工作-现在致力于研发和R补丁。

票数 18
EN

Stack Overflow用户

发布于 2012-07-09 11:19:48

关于tryCatch()的信息,OP已经知道并使用了,但我没有注意到

我认为您缺少的是您的tryCatch()并没有对错误做什么特别的事情,因此您正在以正常的方式引发错误。在交互式使用中,将以通常的方式抛出并处理错误,但在非交互式会话( la Rscript)中运行的脚本中的错误将中止正在运行的脚本。

tryCatch()是一个复杂的函数,它允许捕获和处理R中的各种事件,而不仅仅是错误。但是,默认情况下,它被设置为模仿标准的R错误处理过程;基本上允许R抛出错误并由R报告错误,如果您希望R执行除基本行为之外的任何其他操作,则需要为该错误添加一个特定的处理程序:

代码语言:javascript
复制
> e <- simpleError("test error")
> tryCatch(foo, error = function(e) e,
+          finally = writeLines("There was a problem!"))
There was a problem!
<simpleError in doTryCatch(return(expr), name, parentenv, handler): object 'foo'
not found>

我建议您更详细地阅读?tryCatch,以更好地理解它的功能。

另一种选择是使用try()。要修改您的脚本,我只需:

代码语言:javascript
复制
# this is the line with the uncatchable error
tried <- try(currTs[!(as.POSIXlt(time(currTs))$wday %in% specificWeekDay),] <- NA,
             silent = TRUE)
if(inherits(tried, "try-error")) {
    writeLines("There was an error!")
} else {
    writeLines("Everything worked fine!")
}

关键是保存从try()返回的对象,这样您就可以测试类,并让try()安静地运行。考虑一下不同之处:

代码语言:javascript
复制
> bar <- try(foo)
Error in try(foo) : object 'foo' not found
> bar <- try(foo, silent = TRUE)
> class(bar)
[1] "try-error"

注意,在上面的第一个调用中,错误被捕获为报告为一条消息。在第二种情况下,没有报告。在这两种情况下,都返回类"try-error"的一个对象。

在内部,try()是作为对tryCatch()的单个调用编写的,该调用为错误处理程序设置一个自定义函数,该函数将错误报告为消息并设置返回的对象。您可能希望研究try()的R代码,作为使用tryCatch()的另一个例子。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11393510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档