Getting silent error when checking value of uninitialized reactive variable

Hello guys, I am quite new to developing in Shiny. I came across a rather strange non-specific error in this RegEx:


library(shiny)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("FileInput", label = "Dataset", choices = ls("package:datasets")),
      checkboxInput("cmpr", "Compare with old dataset?"),
      uiOutput("getOldData"),
      actionButton("make", label = "Never does anything")
    ),
    mainPanel(
      h3("Showing  data"),
      tabsetPanel(
        tabPanel("New data", tableOutput("first")),
        tabPanel("Old data", tableOutput("second"))
      )
    )
  )
)


server <- function(input, output, session) {
  datasetInput <- eventReactive(input$FileInput, get(input$FileInput, "package:datasets")) # load dataset

  output$getOldData <- renderUI({
    req(input$cmpr)
    selectInput("FileInputOld", label = "Dataset", choices = ls("package:datasets")) # show options for 2nd dataset if wanted
  })

  datasetInputOld <- eventReactive(input$FileInputOld, get(input$FileInputOld, "package:datasets")) # load 2nd dataset
  observeEvent(datasetInput(), output$first <- renderTable(datasetInput()))
  observeEvent(datasetInputOld(), output$second <- renderTable(datasetInputOld()))

  observeEvent(input$make, {
    if (!(datasetInputOld())) { # gets silent error visible only in debug mode
      print("Error 1") # this never happens
    } else {
      print("Error 2") # this never happens either
    }
  })
}

shinyApp(ui = ui, server = server)

Perhaps it is due to my lack of knowledge, but I find it interesting since the error is silent and non-specific (when accessing datasetInputOld() in the example above R gives: "Error: " and that's it..

Cheers,
Jan

Here is a more minimal reprex to create a silent error of the kind you describe.
I also provide a custom handler you can adopt for your own purpose if you wish.
in contrast to req() which gracefully handles silent errors by silently cancelling the output, this sep (silent error processor) gives your console an explicit error message and provides a kill flag so your can choose whether you wish to have your app 'die' on such an error, or continue with a NULL input or whatever else

library(shiny)

ui <- fluidPage(
  actionButton("testbtn", "btn")
)

server <- function(input, output, session) {
  empty_reactive <- eventReactive(eventExpr = NULL, {
    3
  }, )

  sep <- function(expr, label, kill = TRUE) {
    tryCatch(
      expr = {
        expr
      },
      error = function(e) {
        cat(as.character(e), " ", label, "\n")
      },
      finally = return(if (kill) {
        stop("my own error")
      } else {
        NULL
      })
    )
    expr
  }


  observeEvent(input$testbtn, {
    er <- sep(expr = empty_reactive(),
      label = "**empty_reactive()**",
      kill = FALSE
    )

    cat("The string representation of empty_reactive is ", capture.output(str(er)))
  })
}

shinyApp(ui, server)

Thank you @nirgrahamuk for your prompt reply! If the error is due to NULL value, why can't I overcome it with is.null()? That's actually what I implemented at first, but it still gave this error.

the issue is not a NULL value, the issue is that an eventReactive never triggered an event so has no defined value, which raises a silent shiny error. my code allows this to be detected and treated in arbitrary ways, i.e. as if it were a Null, or as if it was an explicit error.

It seems to me that the default shiny behaviour is good. I'm happy to get a silent error when my reactive objects are in ill defined states. as soon as the event trigger will happen, my app will work with its related parts. Is there something in relation to this type of silent error, that is causing you particular difficulty with constructing your own applications ?

I see...I managed to overcome it with req(). I was curious why couldn't I access it with exist() or is.null() functions.

Thank you!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.