François M.
François M.

Reputation: 4278

Creating a "retry" function in R

I'm trying to do a retry function, which would take in as parameters the thing I want to do, and the number of time it should be tried before stopping.

I've come up with the following :

retry <- function(a, max = 10, init = 0){tryCatch({
  if(init<max) a
}, error = function(e){retry(a, max, init = init+1)})}

Now I want to test it and make sure it works as I intend, but I'd like someone to double check and maybe give me advice on what I should test further.

To test it and see what happens, I modified my function this way :

retry <- function(a, max = 10, init = 0){
  tryCatch({
    if(init<max) {
      print(init) # added part
      a
    }
  }, error = function(e){retry(a, max, init = init+1)})}

I'm using stop() to generate errors and test it. It seems to work more or less as I intend...

> retry(stop())
[1] 0
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9

but...

There were 45 warnings (use warnings() to see them)
> warnings()
Messages d`avis :
1: In doTryCatch(return(expr), name, parentenv, handler) :
  restarting interrupted promise evaluation

    # (the 45 error messages are the same, the last one being the following)

45: In doTryCatch(return(expr), name, parentenv, handler) :
  restarting interrupted promise evaluation

So my questions :

  1. It seems to be working as I want, right ?
  2. Am I safe to ignore the warnings ?

NB : the number of warnings seems to depend on the value of the parameter max, following this pattern :

max   nb of warnings
1     no warning
2     1
3     3
4     6
5     10
6     15
7     21
8     28
9     36
10    45

Upvotes: 2

Views: 1476

Answers (2)

Randy Lai
Randy Lai

Reputation: 3184

You are trying to mess up with the promise a. A correct solution is to use substitute or rlang::enexpr. I have put together some code as the package retry

library(retry)

f <- function(x) {
    if (runif(1) < 0.9) {
        stop("random error")
    }
    x + 1
}

# keep retring when there is a random error
retry(f(1), when = "random error")
#> [1] 2
# keep retring until a requirement is satisified.
retry(f(1), until = function(val, cnd) val == 2)
#> [1] 2
# or using one sided formula
retry(f(1), until = ~ . == 2)
#> [1] 2

Upvotes: 3

IRTFM
IRTFM

Reputation: 263461

There is a suppressWarnings() function to be wrapped around an expression:

retry <- function(a, max = 10, init = 0){suppressWarnings( tryCatch({
  if(init<max) a
}, error = function(e){retry(a, max, init = init+1)}))}

Upvotes: 2

Related Questions