cli
cli copied to clipboard
Passing multiline strings (e.g., `waldo::compare()` outputs) to `cli_abort`
Hi! Is there any way to pass a multi-line string to cli_abort? Specificially, I'm trying to use the output of waldo::compare() to generate more informative error messages, but cli_abort removes all the newline characters from the output, making it very difficult to read.
I tried circumventing the issue by passing compare_obj to rlang::abort via ... but this unfortunately also doesn't work and cli_abort still removes the newline characters, while using rlang::abort directly doesn't result in this behaviour.
df1 <- tibble::tibble(x = 1:3, y = 4:6)
df2 <- tibble::tibble(x = 1:3, y = c(4.0, 5.0, 7.0))
compare_obj <- waldo::compare(df1, df2)
if (length(compare_obj) != 0) {
cli::cli_abort(c("The data frames don't match", compare_obj))
}
#> Error:
#> ! The data frames don't match
#> old vs new y old[1, ] 4 old[2, ] 5 - old[3, ] 6 + new[3, ] 7
#> `old$y` is an integer vector (4, 5, 6) `new$y` is a double vector (4, 5, 7)
if(length(compare_obj) != 0) {
cli::cli_abort(c("The data frames don't match"), body = compare_obj)
}
#> Error:
#> ! The data frames don't match
#> old vs new y old[1, ] 4 old[2, ] 5 - old[3, ] 6 + new[3, ] 7
#> `old$y` is an integer vector (4, 5, 6) `new$y` is a double vector (4, 5, 7)
if(length(compare_obj) != 0) {
rlang::abort(c("The data frames don't match"), body = compare_obj)
}
#> Error:
#> ! The data frames don't match
#> old vs new
#> y
#> old[1, ] 4
#> old[2, ] 5
#> - old[3, ] 6
#> + new[3, ] 7
#> `old$y` is an integer vector (4, 5, 6)
#> `new$y` is a double vector (4, 5, 7)
Session Info
sessionInfo()
#> R version 4.1.2 (2021-11-01)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 22000)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=English_United States.1252
#> [2] LC_CTYPE=English_United States.1252
#> [3] LC_MONETARY=English_United States.1252
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United States.1252
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> loaded via a namespace (and not attached):
#> [1] rstudioapi_0.13 knitr_1.37 magrittr_2.0.1 R.cache_0.15.0
#> [5] rlang_1.0.1 fastmap_1.1.0 fansi_0.5.0 stringr_1.4.0
#> [9] styler_1.6.2 highr_0.9 tools_4.1.2 xfun_0.29
#> [13] R.oo_1.24.0 utf8_1.2.2 cli_3.2.0 withr_2.4.3
#> [17] htmltools_0.5.2 ellipsis_0.3.2 yaml_2.2.1 digest_0.6.29
#> [21] tibble_3.1.6 lifecycle_1.0.1 crayon_1.4.2 purrr_0.3.4
#> [25] R.utils_2.11.0 vctrs_0.3.8 fs_1.5.2 glue_1.6.1
#> [29] evaluate_0.14 rmarkdown_2.11 reprex_2.0.1 stringi_1.7.6
#> [33] compiler_4.1.2 pillar_1.6.4 R.methodsS3_1.8.1 backports_1.4.1
#> [37] pkgconfig_2.0.3
There is no way currently. Ideally \f should work, but it errors:
❯ cli::cli_text("first line\fsecond line")
first line
second line
❯ cli::cli_abort("first line\fsecond line")
Error in vapply(X, FUN, FUN.VALUE = character(1), ..., USE.NAMES = USE.NAMES) :
values must be length 1,
but FUN(X[[1]]) result is length 2
Thank you for the explanation! It would definitely be great to add that as a feature in the future.
Though, what about the fact that passing body = compare_obj to rlang::abort via ... also seems to process the text, instead of just passing the argument to rlang::abort without any modifications (since it works when using rlang::abort directly, I'm assuming the issue is on the cli side). Is this expected behaviour?
Yes, cli re-wraps text to the screen width.
If you are not happy about that, and as a current workaround, you can still use rlang::abort() directly, there is nothing wrong with that.
We are planning to have API for more advanced formatting within cli_abort() at some point.
This will be fixed in #460