Я работаю над общим обработчиком ошибок для большого приложения Shiny. Идея состоит в том, чтобы открыть модальное диалоговое окно с особым стилем в случае возникновения ошибки и таким образом уведомить пользователя о том, что что-то пошло не так. Поскольку приложение состоит из нескольких модулей, я думаю, что использование модального диалога в этом случае работает лучше всего.
В целом это уже работает нормально, но при открытии модального окна ошибки любой другой модальный код может перезаписать этот модальный диалог и, следовательно, пользователь может даже не осознавать, что произошла ошибка. Я не хочу останавливать выполнение приложения при возникновении ошибки, но хочу уведомить пользователя и дать ему возможность изменить ввод и повторить попытку.
Есть ли способ защитить модальное окно от перезаписи другими модальными окнами?
Ниже приведен минимальный пример. При выборе «успех» все отлично. Но при выборе «error» вы увидите только модальное окно ошибки из-за оператора Sys.sleep()
. Без него он будет автоматически перезаписан.
library(shiny)
# load example functions to
source("example-functions.R")
# define UI
ui <- fluidPage(
# application title
titlePanel("Error Handler"),
# sidebar with controls
sidebarLayout(
sidebarPanel(
radioButtons(inputId = "expected_outcome",
label = "Expected Outcome",
choices = list("Success",
"Error")),
actionButton(inputId = "btn_start",
label = "Execute Test")
),
# result message in main panel
mainPanel(
textOutput("user_message")
)
)
)
# server logic
server <- function(input, output) {
# define a symbol for reactive values
rv <- reactiveValues()
# define a reactive variable to display output in the UI and initialise it
rv$user_message <- "Hello World!"
# handler of the user message
output$user_message <- renderText({
rv$user_message
})
observeEvent(input$btn_start, {
message("Start Button was pressed")
# initialise result variable with `NULL`
result <- NULL
if (input$expected_outcome == "Success") {
# set UI text for success
rv$user_message <- "Success!"
} else {
# set UI text for error
rv$user_message <- "Error!"
# show a special error modal
showModal(
div(
id = "general-app-error",
modalDialog(
title = "An error occured.",
"This is the error explanation"
)
)
)
# wait for a second to demonstrate the effect
Sys.sleep(1)
}
# this modal should simulate that some other modal could come up and
# overwrite an error modal so the user will not realise that an error
# happened.
showModal(
modalDialog(
title = "App modal",
"This is the app modal, possibly overwriting other modals.",
size = "m"
)
)
}, ignoreInit = TRUE)
}
# Run the application
shinyApp(ui = ui, server = server)