Condition formatting is a set of operations applied to raw inputs for error messages that includes:

r abort(c( "The error header", "*" = "An error bullet", "i" = "An info bullet", "x" = "A cross bullet" ))

See the tidyverse error style guide for more about this style of error messaging.

While the rlang package embeds rudimentary formatting routines, the main formatting engine is implemented in the cli package.

Formatting messages with cli

By default, rlang uses an internal mechanism to format bullets. It is preferable to delegate formatting to the cli package by using [cli::cli_abort()], [cli::cli_warn()], and [cli::cli_inform()] instead of the rlang versions. These wrappers enable cli formatting with sophisticated paragraph wrapping and bullet indenting that make long lines easier to read. In the following example, a long ! bullet is broken with an indented newline:

rlang::global_entrace(class = "errorr")
#> Error in `rlang::global_entrace()`:
#> ! `class` must be one of "error", "warning", or "message",
#>   not "errorr".
#> i Did you mean "error"?

The cli wrappers also add many features such as interpolation, semantic formatting of text elements, and pluralisation:

inform_marbles <- function(n_marbles) {
  cli::cli_inform(c(
    "i" = "I have {n_marbles} shiny marble{?s} in my bag.",
    "v" = "Way to go {.code cli::cli_inform()}!"
  ))
}

inform_marbles(1)
#> i I have 1 shiny marble in my bag.
#> v Way to go `cli::cli_inform()`!

inform_marbles(2)
#> i I have 2 shiny marbles in my bag.
#> v Way to go `cli::cli_inform()`!

Transitioning from abort() to cli_abort()

If you plan to mass-rename calls from abort() to cli::cli_abort(), be careful if you assemble error messages from user inputs. If these individual pieces contain cli or glue syntax, this will result in hard-to-debug errors and possibly unexpected behaviour.

user_input <- "{base::stop('Wrong message.', call. = FALSE)}"
cli::cli_abort(sprintf("Can't handle input `%s`.", user_input))

To avoid this, protect your error messages by using cli to assemble the pieces:

user_input <- "{base::stop('Wrong message.', call. = FALSE)}"
cli::cli_abort("Can't handle input {.code {user_input}}.")

Enabling cli formatting globally

To enable cli formatting for all abort() calls in your namespace, call [local_use_cli()] in the onLoad hook of your package. Using [on_load()] (make sure to call [run_on_load()] in your hook):

on_load(local_use_cli())

Enabling cli formatting in abort() is useful for:



Try the rlang package in your browser

Any scripts or data that you put into this service are public.

rlang documentation built on Nov. 4, 2023, 9:06 a.m.