有没有办法直接扩展/增加/覆盖当调用我自己没有编写的函数失败时抛出的原始错误消息(即来自基本 R和贡献包的函数)?
例子
考虑以下参考类:
setRefClass("A", fields=list(x1="character"))
指定正确值时没有错误:
new("A", x1="Hello World!")
指定错误值时产生的错误:
> new("A", x1=TRUE)
Error: invalid assignment for reference class field 'x1', should be from class "character" or a subclass (was class "logical")
现在,我想包含有关实际“导致问题”的类的信息。
也许这看起来像这样:
Error: Field assignment error in class 'A':
Invalid assignment for reference class field 'x1', should be from class "character" or a subclass (was class "logical")
我目前实现接近目标的解决方法通常如下所示:
setRefClass("A",
fields=list(x1="character"),
methods=list(
setField=function(field, value) {
tryCatch(
.self$field(name=field, value=value),
warning=function(cond) {
message(cond)
.self$field(field=field, value=value)
},
error=function(cond) {
stop(paste0("Field assignment error in class '",
class(.self), "'\n"),
"ORIGINAL ERROR:\n", as.character(cond)
)
}
)
}
)
)
首先实例化一个“空白”对象后
x <- new("A")
当尝试通过显式 setter 方法为字段设置错误值时,这会给我以下错误:
> x$setField(field="x1", value=TRUE)
Error in value[[3L]](cond) : Field assignment error in class 'A'
ORIGINAL ERROR:
Error: invalid assignment for reference class field 'x1', should be from class "character" or a subclass (was class "logical")
我不喜欢它,原因如下:
它包含很多代码,只需要一点额外的信息,并且这
tryCatch()
部分使代码更难阅读。由于 , AFAIU 的性质,如果我期望一些“常规”行为(即“即使有警告,字段值仍然设置”)
tryCatch()
,我也有义务将.self$field(field=field, value=value)
语句放入函数中。warning()
那是重复的代码。在我看来,通过强制错误消息
as.character()
(为了能够通过等添加信息所必需的 AFAIUpaste()
)有时会切断错误消息。这样我就不得不通过显式的 setter 函数 (
<obj>$setField(<field>, <value>)
) 设置我的字段值,而不是通过“内置”initialize
函数 (new("A", <field>=<value>)
)设置它们