有效调试闪亮的应用程序
Posted
技术标签:
【中文标题】有效调试闪亮的应用程序【英文标题】:Effectively debugging Shiny apps 【发布时间】:2015-11-02 09:51:06 【问题描述】:我有一个复杂的 Shiny 应用程序,它分布在多个文件中,它使用来自多个包的代码。该应用程序在 R Studio 中本地运行时可以工作,但在我的服务器上它会引发一般错误:
错误:不知道如何将“x”转换为“日期”类
这可能是一个简单的编程错误,但准确地找出错误在代码中的哪里被证明是困难的。
如何查找并修复 Shiny 应用程序中的错误来源?有哪些工具可以系统地做到这一点?
Google Groups 上已经有一些类似问题的讨论。
【问题讨论】:
【参考方案1】:日期问题: 服务器端可能使用不同的操作系统,具有不同的默认字符集编码(例如“latin1”、“utf-8”)。有时,在 R 中加载数据会丢失编码。函数 read.csv 有一个参数 encoding="UTF-8",你可以使用它。
为了调试,我依赖于打印语句。我也很想知道其他人是否找到了更系统的方法。
【讨论】:
是的,服务器运行的是 Linux,但我的机器是 Windows。如何让print
语句显示在浏览器控制台中?
打印语句将显示在 R 控制台中。虽然基本的、简单的“到达这部分”和“到达那个部分”语句帮助我调试。我正在使用 RStudio,并运行 runApp() 在 Chrome 浏览器中显示应用程序。
是的,这是 RStudio 中的一个选项,但在远程服务器上运行时这是不可能的。
我相信打印语句会显示在服务器日志中。您可能需要服务器管理员的帮助才能访问这些日志。【参考方案2】:
您可以使用logging
和shinyjs
的组合来实现登录服务器。
install.packages("logging")
install.packages("shinyjs")
在你的 ui.R 中,使用 shinyjs::useShinyjs
绑定 shinyjs
:
library(shinyjs)
shinyUI(
fluidPage(
useShinyjs(),
# etc...
在您的 server.R 中,将 logjs
添加到日志处理程序列表中:
library(magrittr)
library(shinyjs)
library(logging)
basicConfig()
options(shiny.error = function()
logging::logerror(sys.calls() %>% as.character %>% paste(collapse = ", ")) )
shinyServer(function(input, output, session)
printLogJs <- function(x, ...)
logjs(x)
T
addHandler(printLogJs)
# etc...
然后打印一些东西,使用loginfo
。
其他提示
在本地(例如从 RStudio)运行您的应用程序时,使用 options(shiny.error = browser)
或 options(shiny.error = recover)
来确定错误来源。
将尽可能多的业务逻辑放入包和外部脚本中。每当您怀疑它们引起问题时,对它们进行单元测试。 testthat
包可以在这里提供帮助。
如果您希望变量满足某些约束,请添加断言。例如,如果 x
应该是 zoo
,请将 assert_that(is.zoo(x))
放在您的响应式顶部附近。
注意默认的drop
行为。养成在希望结果为data.frame
时指定drop = F
的习惯。
尽量减少代码单元所依赖的变量(选项、环境、缓存、UI 状态等)的数量。弱类型语言已经很难调试了!
尽可能使用正确的 S4 和 S3 类而不是原始 R 结构。
dput
将允许您检查对象的内部结构,并且在尝试在应用程序之外重现错误时非常有用。
尝试在交互式控制台中进行调试,而不是在应用程序中使用 print
。这将允许您更快地迭代。如果无法在应用程序之外进行调试,请尝试在问题代码之前调用browser()
。
从不在非交互式代码中使用sapply
。如果输出为空,它将无法推断出您想要的类型并返回空的list
。如果您的结果应该是vector
,请使用vapply
。如果您的结果应该是list
,请使用lapply
。
您还应该查看来自 RStudio 团队的 Debugging Shiny Applications。
【讨论】:
【参考方案3】:我很惊讶the RStudio Shiny debug article 没有被提及。那篇文章在调试和错误处理方面非常透彻。
您可以查看您的服务器的日志,这应该更直接地解决了OP提出的问题。
【讨论】:
【参考方案4】:options(shiny.error = browser)
添加上面的行并运行代码,当出现错误时它会停止,您可以在stacktace中搜索,如下所示
【讨论】:
以上是关于有效调试闪亮的应用程序的主要内容,如果未能解决你的问题,请参考以下文章