rstudio/shiny

Error traceback when testing shiny app does not report true error location

Closed this issue · 3 comments

mlell commented

When testing code happening inside an observer using testServer() and an error happens, the error location is not reported in the stack trace generated by test_that(). It is only reported by the default handler output that is generated by shiny. In the reproducible example, the stack trace stops at setInputs() rather than following the functions that are called as a results of setInputs() being called.

The expected result would be that testthat and shiny report the same error source, the function "stop()" in the function x(), and give as file and line number test.R:6.

Example application or steps to reproduce the problem

# File "test.R"
library(testthat)
library(shiny)

x <- function(a){
  stop("test")
}

testServer(list(
  ui = flowLayout(actionButton("button", "Push me")), 
  server = function(input, output, session){
    observeEvent(input$button, {
      rlang::try_fetch(
      x(3)
      , error = function(e) rlang::abort("Error in observer", parent = e)
    )
  })
    
  }), {
  test_that("x",{
    session$setInputs(button = 1L)
  })
})

Output:

# [ Full `shiny` stack trace =============================================== ]
  131: <Anonymous>
  130: signalCondition
  129: signal_abort [/tmp/RtmpXwi0DI/R.INSTALL279488583bf75f/rlang/R/cnd-abort.R#861]
  128: rlang::abort [/tmp/RtmpXwi0DI/R.INSTALL279488583bf75f/rlang/R/cnd-abort.R#390]
  127: handlers[[1L]] [~/test.R#14]
  126: h [/tmp/RtmpXwi0DI/R.INSTALL279488583bf75f/rlang/R/cnd-handlers.R#223]
  125: .handleSimpleError
  124: stop
  123: x [~/test.R#5]
  116: observe [~/test.R#12]
  115: <observer:observeEvent(input$button)> [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1459]
  113: valueFunc [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1449]
   96: func [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/bind-event.R#298]
   94: f [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1532]
   93: Reduce
   84: do [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1518]
   83: hybrid_chain [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1558]
   82: observeEvent(input$button) [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/bind-event.R#280]
   81: contextFunc [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/utils.R#1451]
   80: env$runWith [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#160]
   69: ctx$run [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#54]
   68: run [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/reactives.R#1234]
   49: flushCallback [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/reactives.R#1204]
   48: FUN [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#114]
   47: lapply
   46: ctx$executeFlushCallbacks [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#113]
   45: .getReactiveEnvironment()$flush [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#182]
   44: shiny:::flushReact [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/react.R#202]
   43: private$flush [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/mock-session.R#692]
   42: session$setInputs [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/mock-session.R#370]
   41: eval [~/test.R#20]
   40: eval
   31: test_code [/tmp/RtmpXdwe80/R.INSTALLf9c3cb9ccd7/r-lib-testthat-dbe8883/R/test-that.R#188]
   30: test_that [/tmp/RtmpXdwe80/R.INSTALLf9c3cb9ccd7/r-lib-testthat-dbe8883/R/test-that.R#53]
   29: rlang::eval_tidy [~/test.R#19]
    5: testServer [/tmp/Rtmp2wImAI/R.INSTALLe8961d20769/rstudio-shiny-9a35b01/R/test-server.R#121]
    4: eval [~/test.R#8]
    3: eval
    1: source
── Warning: x ─────────────────────────
Error in observe: Error in observer
Caused by error in `x()`:
! test
# [ Incomplete "test_that" stack trace ================================= ]
Backtrace:
     ▆
  1. └─session$setInputs(button = 1L) at ~/test.R:20:5
  2.   └─private$flush() at rstudio-shiny-9a35b01/R/mock-session.R:370:7
  3.     └─shiny:::flushReact() at rstudio-shiny-9a35b01/R/mock-session.R:692:7
  4.       └─.getReactiveEnvironment()$flush() at rstudio-shiny-9a35b01/R/react.R:202:3
  5.         └─ctx$executeFlushCallbacks() at rstudio-shiny-9a35b01/R/react.R:182:9
  6.           └─base::lapply(...) at rstudio-shiny-9a35b01/R/react.R:113:7
  7.             └─shiny (local) FUN(X[[i]], ...)
  8.               └─shiny (local) flushCallback() at rstudio-shiny-9a35b01/R/react.R:114:9
  9.                 └─shiny:::hybrid_chain(...) at rstudio-shiny-9a35b01/R/reactives.R:1204:9
 10.                   └─shiny (local) do() at rstudio-shiny-9a35b01/R/utils.R:1558:5
 11.                     └─base::tryCatch(...) at rstudio-shiny-9a35b01/R/utils.R:1518:5
 12.                       └─base (local) tryCatchList(expr, classes, parentenv, handlers)
 13.                         └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
 14.                           └─value[[3L]](cond)
 15.                             └─shiny (local) catch(e) at rstudio-shiny-9a35b01/R/utils.R:1546:9
 16.                               └─shiny::printError(e) at rstudio-shiny-9a35b01/R/reactives.R:1220:13

── Skip: x ────────────────────────────
Reason: empty test

System details

Browser Version: n/a

Output of sessionInfo():

R version 4.2.2 Patched (2022-11-10 r83330)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 12 (bookworm)

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.11.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.11.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
[1] testthat_3.2.1.1 shiny_1.9.1.9000

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.13       rstudioapi_0.16.0 magrittr_2.0.3    pkgload_1.4.0     xtable_1.8-4      R6_2.5.1          rlang_1.1.4      
 [8] fastmap_1.2.0     tools_4.2.2       waldo_0.6.1       cli_3.6.3         withr_3.0.1       htmltools_0.5.8.1 digest_0.6.37    
[15] rprojroot_2.0.4   lifecycle_1.0.4   crayon_1.5.3      brio_1.1.5        later_1.3.2       promises_1.3.2    cachem_1.1.0     
[22] mime_0.12         compiler_4.2.2    desc_1.4.3        httpuv_1.6.15     renv_1.0.7 
mlell commented

sorry, accidentially chose wrong repo, wanted to report to r-libs/testthat (r-lib/testthat#2040)

Thanks @mlell, this is actually the right place to report this issue

Oh actually, I mis-read the issue, I think it's safe to close here