Getting the stack trace of a function called within a shiny app

Viewed 1011

When a long, complicated function with many multi-layered calls in it throws an error, it can be difficult to understand the bug without seeing the stack trace. But when such a function is called by a shiny app to process its input, the stack trace seems to show only what happened in the app, but not in the function it called. Here's a reprex, based on the code in Section 6.3.1 of Hadley Wickham's Mastering 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)

When 3 is entered by the user, this returns the following to the console:

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

So I can see that the error happened in h(), but not the series of calls, represented by g(), that got me to h(). When the application is run using a file run.R containing the command

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

with App-1 containing a file app.R, the details are a bit different, but the result is the same; traceback() shows only what happened up to the point where the app began to run. What is the best way to capture the stack trace showing how the function that was called by the app reached an error?

2 Answers

You can use the option function of R and run options(shiny.fullstacktrace=TRUE) before you start your app. The stacktrace is then printed in more detail.

The trick is to save your Shiny app and then start the app with runApp("path_to_app_dir") (as described at the end of section 6.2.1 in mastering shiny). Then I get the following stack trace:

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

Admittedly, not completely the same when I run the functions outside of shiny, but close:

 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) 

Related