% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/topic-errors.R
\name{topic-condition-formatting}
\alias{topic-condition-formatting}
\title{Formatting messages with cli}
\description{
Condition formatting is a set of operations applied to raw inputs for error messages that includes:
\itemize{
\item Transforming a character vector of lines to a width-wrapped list of error bullets. This makes it easy to write messages in a list format where each bullet conveys a single important point.
\if{html}{\out{
}}\preformatted{abort(c(
"The error header",
"*" = "An error bullet",
"i" = "An info bullet",
"x" = "A cross bullet"
))
#> Error:
#> ! The error header
#> * An error bullet
#> i An info bullet
#> x A cross bullet
}\if{html}{\out{
}}
See the \href{https://style.tidyverse.org/error-messages.html}{tidyverse error style guide} for more about this style of error messaging.
\item Applying style (emphasis, boldness, ...) and colours to message elements.
}
While the rlang package embeds rudimentary formatting routines, the main formatting engine is implemented in the \href{https://cli.r-lib.org/}{cli package}.
\subsection{Formatting messages with cli}{
By default, rlang uses an internal mechanism to format bullets. It is preferable to delegate formatting to the \href{https://cli.r-lib.org/}{cli package} by using \code{\link[cli:cli_abort]{cli::cli_abort()}}, \code{\link[cli:cli_abort]{cli::cli_warn()}}, and \code{\link[cli:cli_abort]{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 \code{!} bullet is broken with an indented newline:
\if{html}{\out{}}\preformatted{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"?
}\if{html}{\out{
}}
The cli wrappers also add many features such as interpolation, semantic formatting of text elements, and pluralisation:
\if{html}{\out{}}\preformatted{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()`!
}\if{html}{\out{
}}
}
\subsection{Transitioning from \code{abort()} to \code{cli_abort()}}{
If you plan to mass-rename calls from \code{abort()} to \code{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 \href{https://xkcd.com/327/}{unexpected behaviour}.
\if{html}{\out{}}\preformatted{user_input <- "\{base::stop('Wrong message.', call. = FALSE)\}"
cli::cli_abort(sprintf("Can't handle input `\%s`.", user_input))
#> Error: Wrong message.
}\if{html}{\out{
}}
To avoid this, protect your error messages by using cli to assemble the pieces:
\if{html}{\out{}}\preformatted{user_input <- "\{base::stop('Wrong message.', call. = FALSE)\}"
cli::cli_abort("Can't handle input \{.code \{user_input\}\}.")
#> Error:
#> ! Can't handle input `\{base::stop('Wrong message.', call. = FALSE)\}`.
}\if{html}{\out{
}}
}
\subsection{Enabling cli formatting globally}{
To enable cli formatting for all \code{abort()} calls in your namespace, call \code{\link[=local_use_cli]{local_use_cli()}} in the \code{onLoad} hook of your package. Using \code{\link[=on_load]{on_load()}} (make sure to call \code{\link[=run_on_load]{run_on_load()}} in your hook):
\if{html}{\out{}}\preformatted{on_load(local_use_cli())
}\if{html}{\out{
}}
Enabling cli formatting in \code{abort()} is useful for:
\itemize{
\item Transitioning from \code{abort()} to \code{cli::cli_abort()} progressively.
\item Using \code{abort()} when you'd like to disable interpolation syntax.
\item Creating error conditions with \code{error_cnd()}. These condition messages will be automatically formatted with cli as well.
}
}
}
\keyword{internal}