Let me explain with the help of an example.
I have two functions :
fun1 <- function(x) {
assertthat::assert_that(is.numeric(x), msg = 'Not a number')
x
}
fun2 <- function(x) {
assertthat::assert_that(x > 10, msg = 'Number not greater than 10')
x + 10
}
They are called one into another.
fun1(x = fun2(20))
#[1] 30
However, if fun2
fails, I get message from fun1
.
fun1(x = fun2(2))
Error: Not a number
I would expect to get message from fun2
itself which is 'Number not greater than 10'
.
How can I get that?
I know I can break down the function calls like below which will resolve my issue.
y <- fun2(20)
fun1(x = y)
but this is a simplified example. In my real case, it is not possible to do this nor do I want to do it in that way.
Any ideas?
My understanding of the problem is that, assert_that()
passes the ellipsis ...
to see_if()
and in this function the ellipsis is captured with eval(substitute(alist(...))
. This prevents the error in fun2
to be evaluated. The error object is returned from fun2()
and then checked against the condition in fun1()
, checking whether the error object is.numeric
which it isn't so the result is as expected 'Not a number'
.
One way to avoid this is to evaluate the result of fun2()
. In your post you have shown one way, by using an intermediate object. Another way is to evalute the result of fun2()
early using eval(bquote())
. Below we use .()
inside bquote()
to evaluate fun2()
early before the error object that is return is captured by see_if()
. But I guess this is not your desired solution.
fun1 <- function(x) {
eval(bquote(assertthat::assert_that(.(is.numeric(x)), msg = 'Not a number')))
x
}
fun2 <- function(x) {
assertthat::assert_that(x > 10, msg = 'Number not greater than 10')
x + 10
}
fun1(x = fun2(20))
#> [1] 30
fun1(x = fun2(5))
#> Error: Number not greater than 10
Since assert_that
is just a drop-in replacement for stopifnot()
the easier approach is to just use the latter - the error messages are not that bad:
fun1 <- function(x) {
stopifnot("Not a number" = is.numeric(x))
x
}
fun2 <- function(x) {
stopifnot('Number not greater than 10' = x > 10)
x + 10
}
fun1(x = fun2(20))
#> [1] 30
fun1(x = fun2(5))
#> Error in fun2(5): Number not greater than 10
Created on 2023-02-27 by the reprex package (v2.0.1)