rlang icon indicating copy to clipboard operation
rlang copied to clipboard

Document different behaviors of `error` for `check_dots_used()`

Open olivroy opened this issue 7 months ago • 0 comments

Better document the error parameter of check_dots_used().

It redirects to try_fetch() but I don't see the link exactly

https://github.com/r-lib/testthat/commit/932989cc0f1836ef1498c8fe755164f61d03bc35

Also, there is a mention of check_dots_empty() in the check_dots_used() docs.

Maybe worth to add a @family tag to link all the check_dots_*() functions?

Somehow, f3() and f4() only warn for me interactively, but error in reprex.

library(rlang) # 1.1.2
g <- function(x, y, ...) {
  x + y
}
f1 <- function(...) {
  check_dots_used()
  g(...)
}
f1(x = 1, y = 2)
#> [1] 3

try(f1(x = 1, y = 2, z = 3))
#> Error in f1(x = 1, y = 2, z = 3) : Arguments in `...` must be used.
#> ✖ Problematic argument:
#> • z = 3
#> ℹ Did you misspell an argument name?

# Use an `error` handler to handle the error differently.
# For instance to demote the error to a warning and s:
f2 <- function(...) {
  check_dots_used(error = function(cnd) {
    warn(conditionMessage(cnd))
  })
}
f2(x = 1, y = 2, 3, 4, 5)
#> Warning: Arguments in `...` must be used.
#> ✖ Problematic arguments:
#> • x = 1
#> • y = 2
#> • ..3 = 3
#> • ..4 = 4
#> • ..5 = 5
#> ℹ Did you misspell an argument name?

# Use an `error` handler to handle the error differently.
# For instance to demote the error to a warning:
f3 <- function(...) {
  check_dots_empty(
    error = function(cnd) {
      warning(cnd)
    }
  )
  "out"
}
f3(a = 12)
#> Error in `f3()`:
#> ! `...` must be empty.
#> ✖ Problematic argument:
#> • a = 12
#> Backtrace:
#>      ▆
#>   1. └─global f3(a = 12)
#>   2.   └─rlang::check_dots_empty(...)
#>   3.     └─rlang:::action_dots(...)
#>   4.       ├─rlang (local) try_dots(...)
#>   5.       │ └─rlang::try_fetch(expr, error = error)
#>   6.       │   ├─base::tryCatch(...)
#>   7.       │   │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#>   8.       │   │   └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#>   9.       │   │     └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#>  10.       │   └─base::withCallingHandlers(...)
#>  11.       └─rlang (local) action(...)

f4 <- function(...) {
  check_dots_empty(
    error = warning
  )
  "out"
}
f4(a = 1)
#> Error in `f4()`:
#> ! `...` must be empty.
#> ✖ Problematic argument:
#> • a = 1
#> Backtrace:
#>      ▆
#>   1. └─global f4(a = 1)
#>   2.   └─rlang::check_dots_empty(error = warning)
#>   3.     └─rlang:::action_dots(...)
#>   4.       ├─rlang (local) try_dots(...)
#>   5.       │ └─rlang::try_fetch(expr, error = error)
#>   6.       │   ├─base::tryCatch(...)
#>   7.       │   │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#>   8.       │   │   └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#>   9.       │   │     └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#>  10.       │   └─base::withCallingHandlers(...)
#>  11.       └─rlang (local) action(...)
f5 <- function(...) {
  check_dots_empty(
    error = function(cnd) warn(conditionMessage(cnd))
  )
  "out"
}
f5(a = 1)
#> Warning: `...` must be empty.
#> ✖ Problematic argument:
#> • a = 1
#> [1] "out"

Created on 2023-11-30 with reprex v2.0.2

This was improved for https://github.com/r-lib/rlang/issues/1517#issuecomment-1296560775

olivroy avatar Nov 30 '23 22:11 olivroy