From 82840e190467df7fc1705858be62bb2617e266aa Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 11:13:25 -0300 Subject: [PATCH 1/6] feat: Printing errors sent from console --- DESCRIPTION | 5 +++-- NAMESPACE | 2 ++ R/utils.R | 21 ++++++++++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e505fca4..3e9e36ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,7 +19,7 @@ Description: A Grammar-based Toolkit for Scalable and Interactive Genomics Data License: LGPL-3 Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.1 +RoxygenNote: 7.2.3 biocViews: ShinyApps, Genetics, Visualization Imports: htmltools, @@ -29,7 +29,8 @@ Imports: shiny.react, fs, digest, - rjson + rjson, + cli Suggests: config, covr, diff --git a/NAMESPACE b/NAMESPACE index d92b8c3d..924c43f1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -33,4 +33,6 @@ export(visual_channel_x) export(visual_channel_y) export(zoom_to) export(zoom_to_extent) +importFrom(cli,cli_alert_danger) importFrom(shiny,getDefaultReactiveDomain) +importFrom(shiny,observeEvent) diff --git a/R/utils.R b/R/utils.R index 648b92d9..8f33d085 100644 --- a/R/utils.R +++ b/R/utils.R @@ -419,11 +419,30 @@ print.gosling <- function(x, ...) { #' #' shinyApp(ui, server) #' } -#' +#' @importFrom cli cli_alert_danger +#' @importFrom shiny observeEvent #' @return Gosling component for rendering on R shiny apps #' @export #' gosling <- function(component_id, composed_views, clean_braces = TRUE) { + + # Catching error messages coming from the browser + par_env <- parent.frame() + observeEvent( + input$shiny_gosling_js_logs, { + error_message <- paste( + "shiny.gosling - JS console error: ", + input$shiny_gosling_js_logs$name, + "\nMessage: ", + input$shiny_gosling_js_logs$message, + " | Inspect the browser's console for more information about this error" + ) + cli_alert_danger(error_message) + }, + event.env = par_env, + handler.env = par_env + ) + structure( GoslingComponent( component_id = component_id, From e82ded54cb7befd8e5dfc3321425576971663b7c Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 11:50:54 -0300 Subject: [PATCH 2/6] feat: Catching errors --- R/utils.R | 15 +++++++-------- js/src/customGosling.js | 25 ++++++++++++++++++++++++- man/gosling.Rd | 1 - 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/R/utils.R b/R/utils.R index 8f33d085..4c28c8f2 100644 --- a/R/utils.R +++ b/R/utils.R @@ -420,29 +420,28 @@ print.gosling <- function(x, ...) { #' shinyApp(ui, server) #' } #' @importFrom cli cli_alert_danger -#' @importFrom shiny observeEvent +#' @importFrom shiny getDefaultReactiveDomain observeEvent #' @return Gosling component for rendering on R shiny apps #' @export #' gosling <- function(component_id, composed_views, clean_braces = TRUE) { - + # Catching error messages coming from the browser - par_env <- parent.frame() + session <- getDefaultReactiveDomain() + input <- session$input observeEvent( input$shiny_gosling_js_logs, { error_message <- paste( "shiny.gosling - JS console error: ", - input$shiny_gosling_js_logs$name, + session$input$shiny_gosling_js_logs$name, "\nMessage: ", input$shiny_gosling_js_logs$message, " | Inspect the browser's console for more information about this error" ) cli_alert_danger(error_message) - }, - event.env = par_env, - handler.env = par_env + } ) - + structure( GoslingComponent( component_id = component_id, diff --git a/js/src/customGosling.js b/js/src/customGosling.js index 8d1779c0..7312c3d0 100644 --- a/js/src/customGosling.js +++ b/js/src/customGosling.js @@ -1,6 +1,27 @@ import React, { useRef, useEffect } from "react"; import { GoslingComponent } from 'gosling.js'; +/** + * A component to handle errors + */ +class ErrorBoundary extends React.Component { + + constructor(props) { + super(props); + } + + componentDidCatch(error, errorInfo) { + const errorObject = { + 'name': error.name, + 'message': error.message, + }; + Shiny.setInputValue("shiny_gosling_js_logs", errorObject, {priority: 'event'}); + } + render() { + return this.props.children; + } +} + /** * An extension of the GoslingComponent from gosling.js * @param {*} props @@ -15,7 +36,9 @@ export const customGosling = (props) => { return(
- + + +
); }; diff --git a/man/gosling.Rd b/man/gosling.Rd index fd0dde6d..1996ceac 100644 --- a/man/gosling.Rd +++ b/man/gosling.Rd @@ -117,5 +117,4 @@ if (interactive()) { shinyApp(ui, server) } - } From b44c757593e325c5fc481e25b8ade38a4a99f0da Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 14:15:30 -0300 Subject: [PATCH 3/6] fix: using console.warn --- js/src/customGosling.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/customGosling.js b/js/src/customGosling.js index 7312c3d0..32cb3f13 100644 --- a/js/src/customGosling.js +++ b/js/src/customGosling.js @@ -101,7 +101,7 @@ class GoslingComponents { ); } } else { - warnign(`You should provide a viewId to call this method: + console.warn(`You should provide a viewId to call this method: See the docs at http://gosling-lang.org/docs/js-api#zoomtoextent)`); } }; @@ -122,7 +122,7 @@ class GoslingComponents { ); } } else { - warnign(`You should provide a viewId to call this method: + console.warn(`You should provide a viewId to call this method: See the docs at http://gosling-lang.org/docs/js-api#zoomto`); } }; @@ -138,7 +138,7 @@ class GoslingComponents { component.current.api.exportPng(parameters.transparentBackground); } } else { - warnign(`You should provide a component_id to call this method.`); + console.warn(`You should provide a component_id to call this method.`); } }; /** @@ -153,7 +153,7 @@ class GoslingComponents { component.current.api.exportPdf(parameters.transparentBackground); } } else { - warnign(`You should provide a component_id to call this method.`); + console.warn(`You should provide a component_id to call this method.`); } } } From 338a83a4eaf0b032bde71d0976ea34bba520ab61 Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 14:16:08 -0300 Subject: [PATCH 4/6] fix: Prevent adding the same observer twice --- R/utils.R | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/R/utils.R b/R/utils.R index 4c28c8f2..b9860718 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,3 +1,27 @@ +#' Adds an observer to print error messages coming from the JS console +#' @noRd +add_js_error_observer <- function() { + # Catching error messages coming from the browser + session <- getDefaultReactiveDomain() + if (!is.null(session)) { + input <- session$input + if (is.null(session$userData$error_observer)) { + session$userData$error_observer <- observeEvent( + input$shiny_gosling_js_logs, { + error_message <- paste( + "shiny.gosling - JS console error: ", + session$input$shiny_gosling_js_logs$name, + "\nMessage: ", + input$shiny_gosling_js_logs$message, + " | Inspect the browser's console for more information about this error" + ) + cli_alert_danger(error_message) + } + ) + } + } +} + #' Remove null from list #' #' @param r_list An r list with NULL values @@ -426,21 +450,7 @@ print.gosling <- function(x, ...) { #' gosling <- function(component_id, composed_views, clean_braces = TRUE) { - # Catching error messages coming from the browser - session <- getDefaultReactiveDomain() - input <- session$input - observeEvent( - input$shiny_gosling_js_logs, { - error_message <- paste( - "shiny.gosling - JS console error: ", - session$input$shiny_gosling_js_logs$name, - "\nMessage: ", - input$shiny_gosling_js_logs$message, - " | Inspect the browser's console for more information about this error" - ) - cli_alert_danger(error_message) - } - ) + add_js_error_observer() structure( GoslingComponent( From 5aaa277a34954a289332b77dc2301f7ccfabda19 Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 16:25:30 -0300 Subject: [PATCH 5/6] feat: Add utility function to get main session --- R/utils.R | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/R/utils.R b/R/utils.R index b9860718..22112cd5 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,8 +1,33 @@ +#' Gets the main Shiny parent session +#' @importFrom shiny getDefaultReactiveDomain +#' @noRd +get_main_session <- function() { + session <- getDefaultReactiveDomain() + test <- FALSE + max_depth <- 100 + depth <- 0 + while (!test) { + test <- "ShinySession" %in% class(session) + if (!test) { + session <- .subset2(session, "parent") + } + depth <- depth + 1 + if (depth >= max_depth) { + session <- getDefaultReactiveDomain() + test <- TRUE + warning("Max depth reached when running get_main_session") + } + } + session +} + #' Adds an observer to print error messages coming from the JS console +#' @importFrom cli cli_alert_danger +#' @importFrom shiny observeEvent #' @noRd add_js_error_observer <- function() { # Catching error messages coming from the browser - session <- getDefaultReactiveDomain() + session <- get_main_session() if (!is.null(session)) { input <- session$input if (is.null(session$userData$error_observer)) { @@ -443,8 +468,6 @@ print.gosling <- function(x, ...) { #' #' shinyApp(ui, server) #' } -#' @importFrom cli cli_alert_danger -#' @importFrom shiny getDefaultReactiveDomain observeEvent #' @return Gosling component for rendering on R shiny apps #' @export #' From 945a7444340c2a418c0a2599939f7528cd692846 Mon Sep 17 00:00:00 2001 From: federiva Date: Fri, 25 Aug 2023 16:48:38 -0300 Subject: [PATCH 6/6] style: lintr --- R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index 22112cd5..cf3b10bb 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,4 +1,4 @@ -#' Gets the main Shiny parent session +#' Gets the main Shiny parent session #' @importFrom shiny getDefaultReactiveDomain #' @noRd get_main_session <- function() {