From c3f7c50e48a31efb4e5f42ac7ef1df0a679a8563 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 1 Dec 2025 17:20:23 -0600 Subject: [PATCH] feat(pkg-r): Use cli for errors and warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace rlang::abort(), rlang::warn(), and message() with their cli equivalents (cli::cli_abort(), cli::cli_warn(), cli::cli_inform()) throughout the R package. The cli package provides better-formatted, user-friendly messages with consistent styling. Changes: - Add cli to DESCRIPTION Imports - Replace error/warning/message functions in QueryChat.R, data_source.R, querychat_module.R, and utils-ellmer.R - Improve one error message to use cli's structured format with interpolation Closes #114 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pkg-r/DESCRIPTION | 1 + pkg-r/R/QueryChat.R | 8 ++++---- pkg-r/R/data_source.R | 14 ++++++-------- pkg-r/R/querychat_module.R | 2 +- pkg-r/R/utils-ellmer.R | 4 ++-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pkg-r/DESCRIPTION b/pkg-r/DESCRIPTION index e8bd4104..ec391e9a 100644 --- a/pkg-r/DESCRIPTION +++ b/pkg-r/DESCRIPTION @@ -16,6 +16,7 @@ Depends: R (>= 4.1.0) Imports: bslib, + cli, DBI, duckdb, ellmer (>= 0.3.0), diff --git a/pkg-r/R/QueryChat.R b/pkg-r/R/QueryChat.R index 3c214b2d..fe8030fd 100644 --- a/pkg-r/R/QueryChat.R +++ b/pkg-r/R/QueryChat.R @@ -155,7 +155,7 @@ QueryChat <- R6::R6Class( # Validate table name if (!grepl("^[a-zA-Z][a-zA-Z0-9_]*$", table_name)) { - rlang::abort( + cli::cli_abort( "Table name must begin with a letter and contain only letters, numbers, and underscores" ) } @@ -168,7 +168,7 @@ QueryChat <- R6::R6Class( self$greeting <- greeting if (is.null(greeting)) { - rlang::warn(c( + cli::cli_warn(c( "No greeting provided; the LLM will be invoked at conversation start to generate one.", "*" = "For faster startup, lower cost, and determinism, please save a greeting and pass it to QueryChat$new().", "i" = "You can generate a greeting with $generate_greeting()." @@ -196,7 +196,7 @@ QueryChat <- R6::R6Class( if (cleanup) { shiny::onStop(function() { - message("Closing data source...") + cli::cli_inform("Closing data source...") self$cleanup() }) } @@ -455,7 +455,7 @@ QueryChat <- R6::R6Class( #' } server = function(session = shiny::getDefaultReactiveDomain()) { if (is.null(session)) { - rlang::abort( + cli::cli_abort( "$server() must be called within a Shiny server function." ) } diff --git a/pkg-r/R/data_source.R b/pkg-r/R/data_source.R index 73684c55..25f1536f 100644 --- a/pkg-r/R/data_source.R +++ b/pkg-r/R/data_source.R @@ -21,7 +21,7 @@ as_querychat_data_source.data.frame <- function(x, table_name = NULL, ...) { # Infer table name from dataframe name, if not already added table_name <- deparse(substitute(x)) if (is.null(table_name) || table_name == "NULL" || table_name == "x") { - rlang::abort( + cli::cli_abort( "Unable to infer table name. Please specify `table_name` argument explicitly." ) } @@ -31,7 +31,7 @@ as_querychat_data_source.data.frame <- function(x, table_name = NULL, ...) { length(table_name) == 1 && grepl("^[a-zA-Z][a-zA-Z0-9_]*$", table_name, perl = TRUE) if (!is_table_name_ok) { - rlang::abort( + cli::cli_abort( "`table_name` argument must be a string containing a valid table name." ) } @@ -55,18 +55,16 @@ as_querychat_data_source.DBIConnection <- function(x, table_name, ...) { # Character string - keep as is } else { # Invalid input - rlang::abort( + cli::cli_abort( "`table_name` must be a single character string or a DBI::Id object" ) } # Check if table exists if (!DBI::dbExistsTable(x, table_name)) { - rlang::abort(paste0( - "Table ", - DBI::dbQuoteIdentifier(x, table_name), - " not found in database. If you're using a table in a catalog or schema, pass a DBI::Id", - " object to `table_name`" + cli::cli_abort(c( + "Table {DBI::dbQuoteIdentifier(x, table_name)} not found in database.", + "i" = "If you're using a table in a catalog or schema, pass a DBI::Id object to `table_name`" )) } diff --git a/pkg-r/R/querychat_module.R b/pkg-r/R/querychat_module.R index 8e3dc20c..9367b794 100644 --- a/pkg-r/R/querychat_module.R +++ b/pkg-r/R/querychat_module.R @@ -60,7 +60,7 @@ mod_server <- function(id, data_source, greeting, client) { greeting } else { # Generate greeting on the fly if none provided - rlang::warn(c( + cli::cli_warn(c( "No greeting provided; generating one now. This adds latency and cost.", "i" = "Consider using $generate_greeting() to create a reusable greeting." )) diff --git a/pkg-r/R/utils-ellmer.R b/pkg-r/R/utils-ellmer.R index 51002f8d..518c08f5 100644 --- a/pkg-r/R/utils-ellmer.R +++ b/pkg-r/R/utils-ellmer.R @@ -36,8 +36,8 @@ as_querychat_client <- function(client = NULL) { } if (!inherits(client, "Chat")) { - rlang::abort( - "`client` must be an {ellmer} Chat object or a function that returns one.", + cli::cli_abort( + "`client` must be an {ellmer} Chat object or a function that returns one." ) }