Warnings instead of errors from assert_that()?
Asked Answered
N

4

6

I'm using R's assertthat package and am wanting to (temporarily) output a warning instead of an error on assertion failure. What's the easiest way to do that with the assertthat package?

I realize that wanting warnings instead of errors kind of goes against what assertions are supposed to be used for. In the long term, we indeed want to be outputting errors on assertion failure. In the short term, we still want the code to function even with bad input, since the output with bad inputs is still "good enough" for now.

A simple example: suppose I have a function that takes x as input and outputs x+5. I want to output a warning if x!=3. Since we will be using assert_that ultimately, it would be nice if we can use assertthat package for the warning.

In the long term, we'll use this:

> x <- 3
> fn <- function(x) {assert_that(x==3); return(x+5)}
> fn(3)
[1] 8
> fn(4)
 Error: x not equal to 3 

In the short term, here's the best I have so far:

> fn <- function(x) {if(!see_if(x==3)) warning(validate_that(x==3)); return(x+5)}
> fn(3)
[1] 8
> fn(4)
[1] 9
Warning message:
In fn(4) : x not equal to 3

I'm looking for a more concise solution, if possible (best case would be passing an "output_warning" parameter to assert_that, but I don't think that exists).

Nichol answered 1/7, 2015 at 1:20 Comment(0)
C
3

I created a user defined function which accepts a string corresponding to an expression against which you would like to run validate_that() (ultimately assert_that()). The function prints a warning if the assertion fails and remains silent otherwise. See below for usage. You could easily extend this custom function to accept more than one expression if necessary. Note that I also use sys.calls() to obtain the name of the function which called this helper function. This is an important piece of information so you can correlate your warnings with the code that actually generated them.

assert_that_soft <- function(exp) {
                        if (!exp) {
                            print (paste("Error in function:",
                                   parse(sys.calls()[[sys.nframe()-1]])) ) # name of caller
                        }
                    }

Usage:

> fn <- function(x) { assert_that_soft(x==3); return(x+5) }
> fn(3)
[1] 8
> fn(8)
[1] "Error in function: fn(8)"
[1] 13
Catamount answered 1/7, 2015 at 2:4 Comment(0)
N
3

Another option is to wrap assert_that in tryCatch.

fn <- function(x) tryCatch(assert_that(x == 3), error = function(e) warning(e), finally = return(x+5))
fn(3)
# [1] 8
fn(8)
# [1] 13
# Warning message:
# x not equal to 3
Naturalism answered 16/5, 2019 at 14:29 Comment(0)
N
2

I think the easiest way to overwrite the function would be to copy most of the assert_that function as is, and call the new function by the same name so you don't need to change all the code when you go into error mode.

assert_that <- function(..., env=parent.frame()) {
    res <- see_if(..., env=env)
    if (res)
        return(TRUE)
    warning(attr(res, "msg"))
    TRUE
}

fn <- function(x) { assert_that(x==3); return(x+5) }
fn(3)
# [1] 8
fn(8)
# [1] 13
# Warning message:
# In assert_that(x == 3) : x not equal to 3
Nectarous answered 1/7, 2015 at 3:10 Comment(0)
E
0

I am proposing an extension of the assertthat package to allow for simple warnings, see https://github.com/hadley/assertthat/issues/69 any feedback is welcome!

Eyeless answered 7/7, 2021 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.