cnd_message() assembles an error message from two components:
cnd_issue() generic. Methods should return a single line.
cnd_bullets() generic. Methods should return a named vector
of lines. These lines are automatically prefixed with a bullet by
cnd_message() (see the section on error statements).
cnd_message() is automatically called by the
for rlang errors so that errors thrown with
abort() only need to
cnd_bullets(). It can also be called
Note that if you pass a named character vector to
get the same formatting behaviour as
cnd_message(cnd) cnd_issue(cnd, ...) cnd_bullets(cnd, ...) format_bullets(x)
A condition object.
A named character vector of messages. Elements named as
This experimental infrastructure is based on the idea that
sentences in error messages are best kept short and simple. From
this point of view, the best way to present the information is as a
bullet list of simple sentences containing a single clause.
cnd_message() helps following this structure by building an error
message from two parts: the issue and the bullets.
cnd_issue() is the generic for the main error message. It should
be as generic as possible, but since it is a generic it is easy to
override by error subclasses.
cnd_bullets() methods should return a character vector of
sentences. These are automatically prefixed with bullets by
cnd_message(), according to the following scheme:
"i" are prefixed with a blue "info" symbol.
"x" are prefixed with a red "cross" symbol.
Unnamed elements are prefixed with a "*" symbol.
While you are free to lay out the bullets in the order that you like, "x" bullets should usually precede "i" bullets.
Sometimes the generation of an error message depends on the state
of the type checking. In that case, it can be tricky to lazily
generate error messages with
cnd_bullets(): you can either
overspecify your error class hierarchies with one class per state,
or replicate the type-checking control flow within the
cnd_bullets() method. None of these options are ideal.
A better option is to define a
cnd_bullets field in your error
object. This should be a function (or a lambda-formula which will
be passed to
as_function()) with the same signature as
cnd_bullets() methods. This function overrides the
cnd_bullets() generic and can generate an error message tailored
to the state in which the error was constructed.
Note that as a rule,
cnd_issue() should be a general thematic
issues that does not depend on state. For this reason, it isn't
possible to define an overriding method in the condition object.
This infrastructure is experimental. In particular, the output of
cnd_message() is likely to change in the future and you shouldn't
test it verbatim in a way that makes R CMD check fail. Instead, use
testthat::verify_output() to monitor the output without causing
CRAN check failures when it changes.