I'm working on an upload/download function in R Shiny for saving and retrieving user inputs into data frames and other table objects. Files are locally saved to the user machine. I'm using tryCatch() for error handling but I find myself having to be very specific in the types of upload errors to look for, such as column/row mismatches, file type (.RDS) mismatches, and data type mismatches. This is onerous and I'm probably missing other things in an an upload attempt that could crash the code. Is there a way to simply ignore an upload if it would otherwise crash the code for any reasons?
I show code excerpts below only. Let me know if I should instead post a complete working example.
Here is my onerous observer for looking out for the 3 types of crash causes:
# Handle the uploaded file from modal
observeEvent(input$file_upload, {
req(input$file_upload)
tryCatch({
uploaded_data <- readRDS(input$file_upload$datapath)
# Check if the uploaded data is a dataframe
if (!is.data.frame(uploaded_data)) {
stop("Upload target file is of incorrect type. Try again")
}
# Get the expected dataframe structure from user_input()
expected_data <- user_input()
# Check if the dimensions match
expected_cols <- ncol(expected_data)
expected_rows <- nrow(expected_data)
if (ncol(uploaded_data) != expected_cols || nrow(uploaded_data) != expected_rows) {
stop("Upload target file is of incorrect type. Try again")
}
# Check if the data types of each column match
for (i in seq_len(expected_cols)) {
# Get the class (data type) of each column in expected_data and uploaded_data
expected_type <- class(expected_data[[i]])
uploaded_type <- class(uploaded_data[[i]])
# If data types don't match, raise an error
if (expected_type != uploaded_type) {
stop("Upload target file is of incorrect type. Try again.")
}
}
# If everything is fine, update the reactive dataframe and close modal
user_input(uploaded_data)
removeModal() # Close the modal
}, error = function(e) {
# If an error occurs, show a notification and return NULL
showNotification("Upload target file is of incorrect type. Try again.", type = "error", duration = 5)
return(NULL)
})
})
And here is the observer without any sort of upload filtering:
observeEvent(input$file_upload_modal, {
req(input$file_upload_modal)
uploaded_data <- readRDS(input$file_upload_modal$datapath)
user_input(uploaded_data) # Update the reactive user input dataframe
removeModal() # Close the modal once the file is uploaded
})
readRDS(input$file_upload_modal$datapath), you coulduploaded_data <- getValidDataOrNULL(input$file_upload_modal$datapath).globalCallingHandlers()could be used to achieve this for Shiny. Otherwise, maybegetOption('error')`, although I think at that point it might be too late to prevent unwinding.onUnhandledError(). This handler doesn't stop the error or prevent the session from closing, but it can be used to log the error [source].