Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal error with ansi_strwrapwhen string contains \r\n\r in cli_abort() message #667

Open
cderv opened this issue Jan 23, 2024 · 3 comments
Labels
bug an unexpected problem or unintended behavior tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day

Comments

@cderv
Copy link

cderv commented Jan 23, 2024

Running in RStudio R console this leads to an internal error

> cli::cli_abort("processing file: report.qmd\r\n\r  |")
Error:
! ! Internal error in `cli::ansi_strwrap()`
Run `rlang::last_trace()` to see where the error occurred.
> rlang::last_trace()
<error/rlang_error>
Error:
! ! Internal error in `cli::ansi_strwrap()`
---
Backtrace:1. └─cli::cli_abort("processing file: report.qmd\r\n\r  |")
  2.   └─rlang::abort(...)
  3.     └─rlang:::signal_abort(cnd, .file)
  4.       └─rlang::cnd_message(cnd, inherit = TRUE, prefix = TRUE)
  5.         └─rlang:::cnd_message_format_prefixed(cnd, ..., parent = FALSE)
  6.           └─rlang:::cnd_message_format(cnd, ..., alert = alert)
  7.             └─rlang (local) cli_format(glue_escape(lines))
  8.               └─rlang:::.rlang_cli_format(x, cli::format_error)
  9.                 └─cli::cli_format(x, .envir = emptyenv())
 10.                   └─cli::cli_fmt(...)
 11.                     └─cli:::cli__fmt(rec, collapse, strip_newline)
 12.                       ├─base::do.call(app[[msg$type]], msg$args)
 13.                       └─cli (local) `<fn>`(text = `<named list>`, id = "cli-8944-50", class = NULL)
 14.                         └─cli:::clii_bullets(app, text, id, class)
 15.                           └─base::lapply(...)
 16.                             └─cli (local) FUN(X[[i]], ...)
 17.                               └─app$text(text[[i]])
 18.                                 └─cli:::clii_text(app, text)
 19.                                   └─app$xtext(text)
 20.                                     └─cli:::clii__xtext(...)
 21.                                       └─cli::ansi_strwrap(text, exdent = exdent, width = app$get_width(extra = padding))
 22.                                         └─throw(cli_error("Internal error in {.fun cli::ansi_strwrap}"))

The message string is part of the content created by knitr progress bar which uses txtProgressBar.

I encountered this in the context of quarto R package, where quarto render is run with processx::run() and I wanted to use cli_abort() in the error catch
https://github.com/quarto-dev/quarto-r/blob/8a0bcb3a7cf35ce4eb2b412d6d09542cc7b2b35d/R/quarto.R#L41-L48

The full stderr I get in the code above is the following, which leads to same error

msg <- "processing file: report.qmd\r\n\r  |                                                          \r  |                                                    |   0%\r  |                                                          \r  |.................                                   |  33%                  \r  |                                                          \r  |...................................                 |  67% [unnamed-chunk-1]\r\n\n\nQuitting from lines 8-9 [unnamed-chunk-1] (report.qmd)\r\nError:\r\n! true message\r\n\r                                                                                                            \r\nExécution arrêtée\r\n"
> cli::cli_abort(msg)
Error:
! ! Internal error in `cli::ansi_strwrap()`
Run `rlang::last_trace()` to see where the error occurred.
@gaborcsardi
Copy link
Member

Smaller reprex:

❯ cli::ansi_strwrap(cli::col_red("foobar \r\n\r |"))
Error in `cli::ansi_strwrap(cli::col_red("foobar \r\n\r |"))`:
! Internal error in `cli::ansi_strwrap()`
Type .Last.error to see the more details.

❯ .Last.error
<rlib_error_3_0/rlib_error/error>
Error in `cli::ansi_strwrap(cli::col_red("foobar \r\n\r |"))`:
! Internal error in `cli::ansi_strwrap()`
---
Backtrace:
1. cli::ansi_strwrap(cli::col_red("foobar \r\n\r |"))
2. cli:::throw(cli_error("Internal error in {.fun cli::ansi_strwrap}"))

@gaborcsardi gaborcsardi added the bug an unexpected problem or unintended behavior label Jun 20, 2024
@gaborcsardi gaborcsardi added the tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day label Jul 17, 2024
@rundel
Copy link
Contributor

rundel commented Aug 15, 2024

Seems like cli::ansi_strwrap() does not handle the use of \r anywhere between ansi control codes otherwise it is ok

cli::ansi_strwrap(cli::col_red("foobar \r |"))
# Error in `cli::ansi_strwrap(cli::col_red("foobar \r |"))`:
# ! Internal error in `cli::ansi_strwrap()`
# Type .Last.error to see the more details.

ansi_strwrap("foobar \r |")
# <cli_ansi_string>
# [1] foobar |

ansi_strwrap(paste0(cli::col_red("foobar"), "\r |"))
# <cli_ansi_string>
# |] foobar

@rundel
Copy link
Contributor

rundel commented Aug 15, 2024

Adding \r to

cli/R/ansiex.R

Lines 614 to 617 in 2ddcc1a

} else if (xsc %in% c(" ", "\n", "\t")) {
drop <- c(drop, xsidx)
xsidx <- xsidx + 1L
} else if (xwc == " ") {

does avoid the error we're seeing but there is then a secondary issue arrives where it is now possible for the ansi control codes to be out of order resulting in broken output.

cli::ansi_strwrap(cli::col_red("foobar \r |"))
# <cli_ansi_string>
# |] foobar 

cli::ansi_strwrap(cli::col_red("foobar \r |")) |> str()
# 'cli_ansi_string' chr "\033[31mfoobar \r |\033[39m"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior tidy-dev-day 🤓 Tidyverse Developer Day rstd.io/tidy-dev-day
Projects
None yet
Development

No branches or pull requests

3 participants