R Shiny:让程序对不存在的输入/输出名称抛出错误而非静默失败
问题:让Shiny中
$运算符访问不存在的元素时抛出错误 我维护着一个规模不小的Shiny应用,经常记不清元素的命名。如果输错名称,Shiny完全没有任何提示,排查问题特别麻烦。能不能让$运算符在访问不存在的成员时直接抛出错误,存在的话则正常工作?
我试过用get运算符处理inputs,但不管item参数是不是字符串都失败了。还试过下面这段代码:它能在元素不存在时抛出错误,但所有存在的元素都会返回NULL。
`$` = function(obj, item) { if (is.list(obj) || is.reactivevalues(obj)) { item = deparse(substitute(item)) if (!(item %in% names(obj))) stop(sprintf("%s has no member \"%s\"", deparse(obj), item)) return(base::`$`(obj, item)) } else { return(base::`$`(obj, item)) } }
解决方案
你的代码问题在于两个关键点:一是用deparse(obj)会把整个对象的内容转成字符串,而非获取对象的符号名;二是传给base::$``的是字符串形式的item,而不是原始符号,导致无法正确访问成员。另外,reactivevalues对象需要特殊处理来获取准确的成员名称。
修改后的代码如下:
`$` <- function(obj, item) { item_sym <- substitute(item) item_str <- deparse(item_sym) # 仅对list和reactivevalues对象做存在性检查 if (is.list(obj) || inherits(obj, "reactivevalues")) { # 获取对象的有效成员名称 obj_names <- if (inherits(obj, "reactivevalues")) { names(reactiveValuesToList(obj)) } else { names(obj) } if (!(item_str %in% obj_names)) { # 获取对象的符号名,让错误信息更直观 obj_name <- deparse(substitute(obj)) stop(sprintf("对象 %s 不存在成员 \"%s\"", obj_name, item_str), call. = FALSE) } } # 调用基础包的$运算符,传入原始符号以正常访问 base::`$`(obj, item_sym) }
关键修改说明
- 保留
item的原始符号(item_sym),再传给base::$``,确保正常解析命名访问 - 对
reactivevalues对象用reactiveValuesToList(obj)获取准确的成员名称列表 - 用
deparse(substitute(obj))获取对象的符号名(比如input),错误信息更清晰易懂 - 设置
call. = FALSE简化错误输出,避免冗余的函数调用栈信息
测试效果
在Shiny应用中使用时:
- 访问不存在的成员(如
input$wrong_name)会直接抛出错误:对象 input 不存在成员 "wrong_name" - 访问存在的成员(如
input$username)则正常返回对应的值
内容的提问来源于stack exchange,提问作者wing_attack_plan_s
相关产品推荐
相关产品推荐

