Useful if you employ non-user level sub-functions within user-level functions or
if you want string interpolation in error messages. When an error is thrown in the sub
function, the error message will integrate the call of the user-level function, which
is more informative and appropriate for the user. It offers a similar functionality for warning
.
stop_up(..., up = 1, msg = NULL, envir = parent.frame(), verbatim = FALSE)
stopi(..., envir = parent.frame())
warni(..., envir = parent.frame(), immediate. = FALSE)
warn_up(
...,
up = 1,
immediate. = FALSE,
envir = parent.frame(),
verbatim = FALSE
)
Objects that will be coerced to character and will compose the error message.
The number of frames up, default is 1. The call in the error message will be based on the function up
frames up the stack. See examples. If you have many calls to stop_up
/warn_up
with a value of up
different than one, you can use set_up
to change the default value of up
within the function.
A character vector, default is NULL
. If provided, this message will be displayed right under the error message. This is mostly useful when the text contains formatting because the function stop
used to send the error message erases any formatting.
An environment, default is parent.frame()
. Only relevant if the error/warning message contains
interpolation (interpolation is performed with stringmagic). It tells
where the variables to be interpolated should be found. In general you should not worry about this argument.
Logical scalar, default is FALSE
. By default the error/warning message allows variable
interpolation with stringmagic. To disable interpolation,
use verbatim = TRUE
.
Whether the warning message should be prompted directly. Defaults to FALSE
.
These functions are really made for package developers to facilitate the good practice of providing informative user-level error/warning messages.
The error/warning messages allow variable interpolation by making use of stringmagic's interpolation.
stopi()
: Error messages with string interpolation
warni()
: Warnings with string interpolation
warn_up()
: Warnings at the level of user-level functions
For general argument checking, see check_arg()
and check_set_arg()
.
# We create a main user-level function
# The computation is done by an internal function
# Here we compare stop_up with a regular stop
main_function = function(x = 1, y = 2){
my_internal_function(x, y)
}
my_internal_function = function(x, y){
if(!is.numeric(x)){
stop_up("Argument 'x' must be numeric but currently isn't.")
}
# Now regular stop
if(!is.numeric(y)){
stop("Argument 'y' must be numeric but currently isn't.")
}
nx = length(x)
ny = length(y)
if(nx != ny){
# Note that we use string interpolation with {}
warn_up("The lengths of x and y don't match: {nx} vs {ny}.")
}
x + y
}
# Let's compare the two error messages
# stop_up:
try(main_function(x = "a"))
#> Error : the full stack is shown (set this off with setDreamerr_show_stack(FALSE))
#> [01] tryCatch(withCallingHandlers({
#> [02] tryCatchList(expr, classes, parentenv, handlers)
#> [03] tryCatchOne(tryCatchList(expr, names[-nh], parentenv, handlers[-nh]), names[nh], parentenv, handlers...
#> [04] doTryCatch(return(expr), name, parentenv, handler)
#> [05] tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
#> [06] tryCatchOne(expr, names, parentenv, handlers[[1L]])
#> [07] doTryCatch(return(expr), name, parentenv, handler)
#> [08] withCallingHandlers({
#> [09] saveRDS(do.call(do.call, c(readRDS("C:\\Users\\berge028\\AppData\\Local\\Temp\\RtmpyexTgx\\callr-fun...
#> [10] do.call(do.call, c(readRDS("C:\\Users\\berge028\\AppData\\Local\\Temp\\RtmpyexTgx\\callr-fun-3c04235...
#> [11] (function (what, args, quote = FALSE, envir = parent.frame())
#> [12] (function (..., cli_colors, pkgdown_internet)
#> [13] pkgdown::build_site(...)
#> [14] build_site_local(pkg = pkg, examples = examples, run_dont_run = run_dont_run, seed = seed, lazy = la...
#> [15] build_reference(pkg, lazy = lazy, examples = examples, run_dont_run = run_dont_run, seed = seed, ove...
#> [16] purrr::map(topics, build_reference_topic, pkg = pkg, lazy = lazy, examples_env = examples_env, run_d...
#> [17] map_("list", .x, .f, ..., .progress = .progress)
#> [18] with_indexed_errors(i = i, names = names, error_call = .purrr_error_call, call_with_cleanup(map_impl...
#> [19] withCallingHandlers(expr, error = function(cnd) {
#> [20] call_with_cleanup(map_impl, environment(), .type, .progress, n, names, i)
#> [21] .f(.x[[i]], ...)
#> [22] withCallingHandlers(data_reference_topic(topic, pkg, examples_env = examples_env, run_dont_run = run...
#> [23] data_reference_topic(topic, pkg, examples_env = examples_env, run_dont_run = run_dont_run)
#> [24] run_examples(tags$tag_examples[[1]], env = if (is.null(examples_env)) NULL else new.env(parent = exa...
#> [25] highlight_examples(code, topic, env = env)
#> [26] downlit::evaluate_and_highlight(code, fig_save = fig_save_topic, env = child_env(env), output_handle...
#> [27] evaluate::evaluate(code, child_env(env), new_device = TRUE, output_handler = output_handler)
#> [28] evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, debug = debug, last = i == leng...
#> [29] timing_fn(handle(ev <- withCallingHandlers(withVisible(eval_with_user_handlers(expr, envir, enclos, ...
#> [30] handle(ev <- withCallingHandlers(withVisible(eval_with_user_handlers(expr, envir, enclos, user_handl...
#> [31] try(f, silent = TRUE)
#> [32] tryCatch(expr, error = function(e) {
#> [33] tryCatchList(expr, classes, parentenv, handlers)
#> [34] tryCatchOne(expr, names, parentenv, handlers[[1L]])
#> [35] doTryCatch(return(expr), name, parentenv, handler)
#> [36] withCallingHandlers(withVisible(eval_with_user_handlers(expr, envir, enclos, user_handlers)), warnin...
#> [37] withVisible(eval_with_user_handlers(expr, envir, enclos, user_handlers))
#> [38] eval_with_user_handlers(expr, envir, enclos, user_handlers)
#> [39] eval(expr, envir, enclos)
#> [40] eval(expr, envir, enclos)
#> [41] try(main_function(x = "a"))
#> [42] tryCatch(expr, error = function(e) {
#> [43] tryCatchList(expr, classes, parentenv, handlers)
#> [44] tryCatchOne(expr, names, parentenv, handlers[[1L]])
#> [45] doTryCatch(return(expr), name, parentenv, handler)
#> [46] main_function(x = "a")
#> [47] my_internal_function(x, y)
#> [48] stop_up("Argument 'x' must be numeric but currently isn't."):
#> Argument 'x' must be numeric but currently isn't.
# => the user understands that the problem is with x
# Now compare with the regular stop:
try(main_function(y = "a"))
#> Error in my_internal_function(x, y) :
#> Argument 'y' must be numeric but currently isn't.
# Since the user has no clue of what my_internal_function is,
# s/he will be puzzled of what to do to sort this out
# Same with the warning => much clearer with warn_up
main_function(1, 1:2)
#> Warning: In main_function(1, 1:2):
#> The lengths of x and y don't match: 1 vs 2.
#> [1] 2 3