From 518d67dbb40547298d95b33d9e77fa268d0478bb Mon Sep 17 00:00:00 2001 From: olivroy Date: Mon, 4 Dec 2023 16:19:58 -0500 Subject: [PATCH 1/3] Improve error message --- NEWS.md | 2 ++ R/utils.R | 25 ++++++++++++--------- tests/testthat/helper-render_formats.R | 5 +---- tests/testthat/test-input_data_validation.R | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index c799a5237b..73dfca3588 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ * `gtsave()` now returns the file path invisibly instead of `TRUE` (@olivroy, #1478). +* Most functions in gt receive a better error message if they don't provide a `gt_tbl` as an input (@olivroy, #1504). + # gt 0.10.0 ## Nanoplots diff --git a/R/utils.R b/R/utils.R index 6f25637c52..e7abe5a5a4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -86,10 +86,11 @@ is_nonempty_string <- function(x) { #' @param data The input `data` object that is to be validated. #' #' @noRd -stop_if_not_gt_tbl <- function(data) { +stop_if_not_gt_tbl <- function(data, call = rlang::caller_env()) { if (!is_gt_tbl(data = data)) { cli::cli_abort( - "The `data` provided is not a `gt_tbl` object." + "`data` must be a `gt_tbl` object, not {.obj_type_friendly {data}}.", + call = call ) } } @@ -99,23 +100,25 @@ stop_if_not_gt_tbl <- function(data) { #' @param data The input `data` object that is to be validated. #' #' @noRd -stop_if_not_gt_group <- function(data) { +stop_if_not_gt_group <- function(data, call = caller_env()) { if (!is_gt_group(data = data)) { cli::cli_abort( - "The `data` provided is not a `gt_group` object." + "`data` must be a `gt_group` object, not {.obj_type_friendly {data}}.", + call = call ) } } -#' Stop any function if object is neither `gt_tbl` nor `gt_group` +#' Stop any function if object is neither `gt_tbl` nor `gt_ group` #' #' @param data The input `data` object that is to be validated. #' #' @noRd -stop_if_not_gt_tbl_or_group <- function(data) { +stop_if_not_gt_tbl_or_group <- function(data, call = rlang::caller_env()) { if (!is_gt_tbl(data = data) && !is_gt_group(data = data)) { cli::cli_abort( - "The `data` provided is neither a `gt_tbl` nor a `gt_group` object." + "`data` must either be a `gt_tbl` or a `gt_group`, not object{.obj_type_friendly {data}}.", + call = error_call ) } } @@ -243,7 +246,7 @@ get_date_format <- function(date_style) { cli::cli_abort(c( "If using a numeric value for a `date_style`, it must be ", "between `1` and `{nrow(date_format_tbl)}`.", - "*" = "Use `info_date_style()` for a useful visual reference." + "*" = "Use {.run [info_date_style](gt::info_date_style(opt_interactive = TRUE))} for a useful visual reference." )) } } @@ -254,7 +257,7 @@ get_date_format <- function(date_style) { if (!(date_style %in% date_format_tbl$format_name)) { cli::cli_abort(c( "If using a `date_style` name, it must be in the valid set.", - "*" = "Use `info_date_style()` for a useful visual reference." + "*" = "Use {.run [info_date_style](gt::info_date_style(opt_interactive = TRUE))} for a useful visual reference." )) } @@ -296,7 +299,7 @@ get_time_format <- function(time_style) { cli::cli_abort(c( "If using a numeric value for a `time_style`, it must be between `1` and `{nrow((time_format_tbl))}`.", - "*" = "Use `info_time_style()` for a useful visual reference." + "*" = "Use {.run [info_time_style](gt::info_time_style(interactive = TRUE))} for a useful visual reference." )) } } @@ -307,7 +310,7 @@ get_time_format <- function(time_style) { if (!(time_style %in% time_format_tbl$format_name)) { cli::cli_abort(c( "If using a `time_style` name, it must be in the valid set.", - "*" = "Use `info_time_style()` for a useful visual reference." + "*" = "Use {.run [info_time_style](gt::info_time_style(interactive = TRUE))} for a useful visual reference." )) } diff --git a/tests/testthat/helper-render_formats.R b/tests/testthat/helper-render_formats.R index a12aa74747..8f7905b1f7 100644 --- a/tests/testthat/helper-render_formats.R +++ b/tests/testthat/helper-render_formats.R @@ -1,8 +1,5 @@ # Testable version of the `render_formats()` function render_formats_test <- function(data, context) { - - data %>% - build_data(context = context) %>% - .$`_body` + build_data(data, context = context)$`_body` } diff --git a/tests/testthat/test-input_data_validation.R b/tests/testthat/test-input_data_validation.R index 9e06053913..0214c4b6e0 100644 --- a/tests/testthat/test-input_data_validation.R +++ b/tests/testthat/test-input_data_validation.R @@ -1,6 +1,6 @@ test_that("All exported functions validate the incoming `data` object", { - regexp_stop <- "The `data` provided is not a `gt_tbl` object" + regexp_stop <- "`data` must be a `gt_tbl` object" # Test the `exibble` tibble with all exported functions; # don't provide values for any arguments and ensure that From 7bbdf35517daa2b5fa1426c7094c7a49f6834324 Mon Sep 17 00:00:00 2001 From: olivroy Date: Mon, 4 Dec 2023 16:25:27 -0500 Subject: [PATCH 2/3] Revert unintended --- R/utils.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/utils.R b/R/utils.R index e7abe5a5a4..78024bf87a 100644 --- a/R/utils.R +++ b/R/utils.R @@ -109,7 +109,7 @@ stop_if_not_gt_group <- function(data, call = caller_env()) { } } -#' Stop any function if object is neither `gt_tbl` nor `gt_ group` +#' Stop any function if object is neither `gt_tbl` nor `gt_group` #' #' @param data The input `data` object that is to be validated. #' @@ -246,7 +246,7 @@ get_date_format <- function(date_style) { cli::cli_abort(c( "If using a numeric value for a `date_style`, it must be ", "between `1` and `{nrow(date_format_tbl)}`.", - "*" = "Use {.run [info_date_style](gt::info_date_style(opt_interactive = TRUE))} for a useful visual reference." + "*" = "Use `info_date_style()` for a useful visual reference." )) } } @@ -257,7 +257,7 @@ get_date_format <- function(date_style) { if (!(date_style %in% date_format_tbl$format_name)) { cli::cli_abort(c( "If using a `date_style` name, it must be in the valid set.", - "*" = "Use {.run [info_date_style](gt::info_date_style(opt_interactive = TRUE))} for a useful visual reference." + "*" = "Use `info_date_style()` for a useful visual reference." )) } @@ -299,7 +299,7 @@ get_time_format <- function(time_style) { cli::cli_abort(c( "If using a numeric value for a `time_style`, it must be between `1` and `{nrow((time_format_tbl))}`.", - "*" = "Use {.run [info_time_style](gt::info_time_style(interactive = TRUE))} for a useful visual reference." + "*" = "Use `info_time_style()` for a useful visual reference." )) } } @@ -310,7 +310,7 @@ get_time_format <- function(time_style) { if (!(time_style %in% time_format_tbl$format_name)) { cli::cli_abort(c( "If using a `time_style` name, it must be in the valid set.", - "*" = "Use {.run [info_time_style](gt::info_time_style(interactive = TRUE))} for a useful visual reference." + "*" = "Use `info_time_style()` for a useful visual reference." )) } From f4e39a0151045acd33934dd0cefdb09a69d99489 Mon Sep 17 00:00:00 2001 From: olivroy Date: Mon, 4 Dec 2023 16:39:53 -0500 Subject: [PATCH 3/3] Make code more uniform. --- R/utils.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/utils.R b/R/utils.R index 78024bf87a..c93b263ce8 100644 --- a/R/utils.R +++ b/R/utils.R @@ -86,7 +86,8 @@ is_nonempty_string <- function(x) { #' @param data The input `data` object that is to be validated. #' #' @noRd -stop_if_not_gt_tbl <- function(data, call = rlang::caller_env()) { +# Use rlang::caller_env() to inform user of the precise location of failure. +stop_if_not_gt_tbl <- function(data, call = caller_env()) { if (!is_gt_tbl(data = data)) { cli::cli_abort( "`data` must be a `gt_tbl` object, not {.obj_type_friendly {data}}.", @@ -114,10 +115,10 @@ stop_if_not_gt_group <- function(data, call = caller_env()) { #' @param data The input `data` object that is to be validated. #' #' @noRd -stop_if_not_gt_tbl_or_group <- function(data, call = rlang::caller_env()) { +stop_if_not_gt_tbl_or_group <- function(data, call = caller_env()) { if (!is_gt_tbl(data = data) && !is_gt_group(data = data)) { cli::cli_abort( - "`data` must either be a `gt_tbl` or a `gt_group`, not object{.obj_type_friendly {data}}.", + "`data` must either be a `gt_tbl` or a `gt_group`, not {.obj_type_friendly {data}}.", call = error_call ) }