如何捕获Shiny应用崩溃/断开连接时的回溯信息
捕获Shiny应用崩溃/断开连接时的回溯信息
可行方案
方案1:全局错误捕获配置
在应用启动前设置全局错误处理函数,所有未被捕获的崩溃都会触发该函数,自动记录回溯信息:
library(shiny) # 全局错误处理:捕获回溯并写入日志 options(error = function() { tb <- traceback(x = sys.calls(), max.lines = Inf) writeLines(capture.output(tb), "shiny_crash_log.txt") }) ui <- fluidPage( actionButton("crash", "Crash") ) server <- function(input, output, session) { observeEvent(input$crash, { print(error) # 模拟崩溃:调用不存在的对象 }) } shinyApp(ui, server)
方案2:tryCatch包裹风险代码
对明确可能崩溃的代码块,用tryCatch显式捕获错误,直接获取回溯:
library(shiny) ui <- fluidPage( actionButton("crash", "Crash") ) server <- function(input, output, session) { observeEvent(input$crash, { tryCatch({ print(error) # 模拟崩溃 }, error = function(e) { # 捕获错误信息与回溯 tb <- traceback(x = sys.calls(), max.lines = Inf) message("崩溃回溯信息:") print(tb) # 写入会话专属日志 writeLines(capture.output(c(e$message, tb)), paste0("crash_", session$token, ".txt")) # 可选:主动断开会话 session$close() }) }) } shinyApp(ui, server)
方案3:会话级错误追踪
利用session$onFlush在每次会话刷新时绑定错误处理,确保会话内的崩溃被记录:
library(shiny) ui <- fluidPage( actionButton("crash", "Crash") ) server <- function(input, output, session) { # 每次刷新时设置会话专属错误处理 session$onFlush(function() { old_error_opt <- getOption("error") options(error = function() { tb <- traceback(x = sys.calls(), max.lines = Inf) writeLines(capture.output(tb), paste0("session_", session$token, "_crash.txt")) # 恢复原有错误处理配置 options(error = old_error_opt) }) }, once = FALSE) observeEvent(input$crash, { print(error) }) } shinyApp(ui, server)
原方法无效的原因
onStop和session$onEnded仅在会话正常结束(如用户主动关闭页面、应用主动停止)时触发,崩溃会直接中断代码执行流程,无法触发这些收尾函数,因此无法捕获回溯信息。
内容的提问来源于stack exchange,提问作者JohnCoene
相关产品推荐
相关产品推荐

