Получение трассировки стека функции, вызываемой в блестящем приложении

#r #shiny

#r #блестящий

Вопрос:

Когда длинная сложная функция со множеством многоуровневых вызовов выдает ошибку, может быть трудно понять ошибку, не видя трассировку стека. Но когда такая функция вызывается приложением shiny для обработки своих входных данных, трассировка стека, похоже, показывает только то, что произошло в приложении, но не в функции, которую оно вызвало. Вот повторный вариант, основанный на коде из раздела 6.3.1 книги Хэдли Уикхема «Освоение Shiny«:

 library(shiny)

f <- function(.x){
  # A function with many multi-layered calls.
  x_new <- as.numeric(.x)
  f_result <- g(x_new)
  return(f_result)
}

g <- function(.y){
  # Represents a few layers of calls between f() and h().
  y_new <- min(.y, 1024)
  g_result <- h(y_new)
  return(g_result)
}

h <- function(.z){
  # A call several layers down.
  #
  if(.z == 3) stop("Value of 3 not allowed")
  h_result <- .z * 2
  return(h_result)
}

ui <- fluidPage(
  selectInput("n", "N", 1:10),
  plotOutput("plot")
)
server <- function(input, output, session) {
  output$plot <- renderPlot({
    n <- f(input$n)
    plot(head(cars, n))
  })
}
shinyApp(ui, server)
  

Когда пользователь вводит 3, это возвращает на консоль следующее:

 Warning: Error in h: Value of 3 not allowed
  [No stack trace available]
  

Итак, я вижу, что ошибка произошла в h (), но не в серии вызовов, представленных g (), которая привела меня к h (). Когда приложение запускается с использованием файла , запустите.R, содержащий команду

 runApp('T://someNetworkDirectory//App-1', launch.browser=TRUE)
  

в приложении-1, содержащем файл app.R, детали немного отличаются, но
результат тот же; traceback() показывает только то, что происходило до
точка, с которой приложение начало запускаться. Каков наилучший способ получить трассировку стека, показывающую, как функция, вызванная приложением, достигла ошибки?

Ответ №1:

Вы можете использовать option функцию R и выполнить options(shiny.fullstacktrace=TRUE) перед запуском своего приложения. Затем трассировка стека печатается более подробно.

Ответ №2:

Хитрость заключается в том, чтобы сохранить ваше приложение Shiny, а затем запустить приложение с помощью runApp("path_to_app_dir") (как описано в конце раздела 6.2.1 «Освоение shiny»). Затем я получаю следующую трассировку стека:

 Warning: Error in h: Value of 3 not allowed
  171: stop
  170: h [C:pathShinyshiny_example/app.R#20]
  169: g [C:pathShinyshiny_example/app.R#13]
  168: f [C:pathShinyshiny_example/app.R#6]
  167: renderPlot [C:pathShinyshiny_example/app.R#31]
  165: func
  125: drawPlot
  111: <reactive:plotObj>
   95: drawReactive
   82: origRenderFunc
   81: output$plot
    1: runApp
  

По общему признанию, не совсем то же самое, когда я запускаю функции вне shiny, но закрываю:

  Error in h(y_new) : Value of 3 not allowed 
4.
stop("Value of 3 not allowed") 
3.
h(y_new) 
2.
g(x_new) 
1.
f(3) 

  

Комментарии:

1. Это то, что я вижу на экране. Однако traceback() показывает и, что более важно для моей цели, bugReport <- .traceback() сохраняет нечто совершенно иное. То, что я нахожу там, пропуская хороший фрагмент в середине, выглядит следующим образом: 11: Sys.sleep(0.001) 10: withCallingHandlers(expr, error = doCaptureStack) 9: globals$domain$wrapSync(expr) ... 3: eval(ei, envir) 2: withVisible(eval(ei, envir)) 1: source("run.R") где run.R находится файл, содержащий runApp команду. Итак, ничего о функциях f, g и h там нет.