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

cli_inform doesn't invoke cli.default_handler #712

Open
inferentialist opened this issue Aug 7, 2024 · 5 comments
Open

cli_inform doesn't invoke cli.default_handler #712

inferentialist opened this issue Aug 7, 2024 · 5 comments

Comments

@inferentialist
Copy link

Based on https://cli.r-lib.org/articles/semantic-cli.html#cli-messages, I would expect cli_abort, cli_warn, and cli_inform to call the handler specified in cli.default_handler. However, these particular functions wrap their rlang analogues and seemingly wind up on another code path.

Here's a simple reproducible example. The first expect_output behaves as expected; the second, fails.

test_that("cli_inform doesn't call cli.default_handler", {

  test_case <- function(cli_op) {
    withr::with_options(
      list(
        cli.default_handler = function(msg) cat("handled")
      ),
      cli_op("foo")
    )
  }

  expect_output(
    test_case(cli::cli_alert),
    "handled"
  )

  expect_output(
    test_case(cli::cli_inform),
    "handled"
  )
})

Hoping this has an easy workaround; and apologies if I overlooked something in the documentation. Thanks for all your work on the cli project!

@gaborcsardi
Copy link
Member

Yes, that's a mistake in the documentation, those functions indeed do not use the regular cli code path.

@inferentialist
Copy link
Author

Thanks for the clarification.

Wondering if something like this might be a palatable alternative:

  alt_inform <- function(message, ..., .envir = parent.frame()) {
    outer_cnd <- catch_cnd(
      rlang::inform(cli::format_message(message, .envir = .envir), ...)
    )

    cnd <- catch_cnd(
      cli::cli_verbatim(
        format(outer_cnd)
      )
    )

    handler <- getOption("cli.default_handler", cli:::cli_server_default)
    handler(cnd)

    cnd_signal(outer_cnd)
    invisible(NULL)
  }

@gaborcsardi
Copy link
Member

cli_inform() is basically the same as cli_bullets(), so you can probably use that instead.

@inferentialist
Copy link
Author

My hope was to use the default handler functionality to intercept cli_* calls and reroute them into a log. In general, I wouldn't have access to the source code that invokes the cli_* calls.

Seems like it wasn't designed for this use case. No worries. Thanks for the comments.

@gaborcsardi
Copy link
Member

gaborcsardi commented Aug 7, 2024

You can always catch all messages, if that helps with your use case:

msgs <- list(); withCallingHandlers(cli::cli_inform("good to know"), message = function(m) msgs <<- c(msgs, list(m)))
good to knowmsgs
[[1]]
<message/rlang_message>
Message:
good to know

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants