cli icon indicating copy to clipboard operation
cli copied to clipboard

Error overwrites current progress bar

Open rpatin opened this issue 3 years ago • 4 comments

Hi all, First thanks for your work with this package, which is really nice to use. I don't think this is directly an issue with the package, but I could not find answers elsewhere. When an error occurs in a script using progress bar, the error message is written over the last iteration of the progress bar, which is quite annoying. I have tried using custom functions in options(error = myfunction) but it seems it is executed after the error so it does not change anything.

Here is a reproducible example :

cli::cli_progress_step("This is a very very very very very long test message")
stop("small error")

Would you have any advice on how to solve that ? Thanks in advance, Rémi

rpatin avatar Mar 17 '22 09:03 rpatin

If you are throwing the error then you can clear the status bar first.

{
cli::cli_progress_step("This is a very very very very very long test message")
cli::cli_progress_done(result = "failed")
stop("small error")
}
#> ✖ This is a very very very very very long test message [5ms]
#> Error: small error

Unfortunately I could not find a nice solution if the error is thrown elsewhere. R prints the error message very eagerly, and there are only risky solutions to prevent that.

gaborcsardi avatar Mar 17 '22 09:03 gaborcsardi

One possible solution would be to have a helper function that adds spaces + \r (or an ANSI delete-to-line sequence) to the error message. E.g. this works in a terminal:

{
cli::cli_progress_step("This is a very very very very very long test message")
stop("\033[Ksmall error")
}
#> ✔ This is a very very very very very long test message [46.1s]
#> Error: small error

If you are inside a function, like most of the time, then you get:

local({
  cli::cli_progress_step("This is a very very very very very long test message")
  stop("\033[Ksmall error")
})
#> Error in eval(quote({ : small error
#> ✖ This is a very very very very very long test message [165ms]

gaborcsardi avatar Mar 17 '22 09:03 gaborcsardi

Thanks for the solution. This should work for error that I handle in the functions (if I throw the error).

As you said before, for errors that comes from external functions (i.e. I have wrong data in a data.frame and dplyr throws an error) this is much harder (and not recommended) to try and add this character to their error message.

rpatin avatar Mar 17 '22 09:03 rpatin

It would be probably better to print the error after the progress message, even though it will still be on the same line. That what happens e.g. with the txtProgressBar() base function:

testit <- function(x = sort(runif(20)), ...) {
  pb <- txtProgressBar(...)
  for(i in c(0, x, 1)) {
    Sys.sleep(0.5)
    setTxtProgressBar(pb, i)
    if (runif(1) < 0.2) stop("oops")
  }
  Sys.sleep(1)
  close(pb)
}

testit()
#> =======================================Error in testit() : oops

We could also try to ask R-core for a way to print a newline before the error message, that would be useful for txtProgressBar() as well, and many other places.

gaborcsardi avatar Aug 23 '22 08:08 gaborcsardi