You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何捕获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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:50:16