2

Warning messsages are output in the console, but how do I get these warnings to appear in the UI so the user can see them without looking at the console?

Mr. Bugle
  • 325
  • 2
  • 12

1 Answers1

5

You can use tryCatch to store a warning object. You can then put the message anywhere on your UI.

library(shiny)

ui <- fluidPage(
  actionButton("btn", "click me")
)

server <- function(input, output)
{
  observeEvent(input$btn, {
    #x <- (1:3 * 1:2)  # this generates a warning
    #warning("manually generated warning message")
    #mess <- names(last.warning)
    a <- tryCatch(warning(Sys.time()), warning=function(w) { w })
    mess <- a$message
    showNotification(mess)
  })
}

runApp(list(ui=ui, server=server))

Getting both message and value

If the operation is not heavy, an easy way is to run it twice: once with tryCatch and the other without.

library(shiny)

ui <- fluidPage(
  actionButton("btn", "click me")
)

server <- function(input, output)
{
  observeEvent(input$btn, {

    x <- tryCatch(1:3 * 1:2, warning=function(w) { w })
    if (inherits(x, "simpleWarning")) {
      mess <- x$message
      showNotification(mess)
      x <- 1:3 * 1:2
    }
    print(x)
  })
}

runApp(list(ui=ui, server=server))

If running the same operation twice is not desirable, then use the following trick (See this SO thread)

library(shiny)

ui <- fluidPage(
  actionButton("btn", "click me")
)

server <- function(input, output)
{
  withWarnings <- function(expr) {
    myWarnings <- NULL
    wHandler <- function(w) {
      myWarnings <<- c(myWarnings, list(w))
      invokeRestart("muffleWarning")
    }
    val <- withCallingHandlers(expr, warning = wHandler)
    list(value = val, warnings = myWarnings)
  } 

  observeEvent(input$btn, {
    x <- withWarnings(1:3 * 1:2)
    if (!is.null(x$warnings)) {
      for (w in x$warnings) showNotification(w$message)

    }
  })
}

runApp(list(ui=ui, server=server))
Kota Mori
  • 6,510
  • 1
  • 21
  • 25
  • I tried to run your code, but got this message: Warning: Error in observeEventHandler: object 'last.warning' not found – Mr. Bugle Jun 23 '17 at 13:54
  • Really. Do you see warning message in the console? – Kota Mori Jun 23 '17 at 13:57
  • Yeah, the shiny app closes when I press the actionButton, and that warning is in the console. – Mr. Bugle Jun 23 '17 at 14:02
  • Edited my answer. Can you try this? And if this is still not working, I would like to see the result of `sessionInfo()`. – Kota Mori Jun 23 '17 at 14:05
  • Same issue. Here's my sessionInfo() `R version 3.4.0 (2017-04-21) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows >= 8 x64 (build 9200) Matrix products: default locale: [1] LC_COLLATE=English_United States.1252 [2] LC_CTYPE=English_United States.1252 [3] LC_MONETARY=English_United States.1252 [4] LC_NUMERIC=C [5] LC_TIME=English_United States.1252 attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] compiler_3.4.0 tools_3.4.0 ` – Mr. Bugle Jun 23 '17 at 14:09
  • Hmm. Can you simply type this on console? `warning("foo"); warnings(); last.warning`. What do you get? – Kota Mori Jun 23 '17 at 14:16
  • That works `Warning message: foo Warning message: foo $foo NULL` And if I run the shiny app after I run that line, it works but the notification outputs "foo" so it seems like it's taking whatever exists in the console, not the shiny server – Mr. Bugle Jun 23 '17 at 14:26
  • Edited again. This time warning message is set to current time. Does message pop up? – Kota Mori Jun 23 '17 at 14:34
  • Say I want to output the result of `x <- (1:3 * 1:2)` Is there a way to show the output from that as well as the warning? – Mr. Bugle Jun 23 '17 at 14:49
  • Figured it out, need to use `finally=` within `tryCatch`. Thanks for your help – Mr. Bugle Jun 23 '17 at 15:00