How to retry a statement on error?

Viewed 19000

How can I simply tell R to retry a statement a few times if it errors? E.g. I was hoping to do something like:

tryCatch(dbGetQuery(...),           # Query database
    error = function(e) {
        if (is.locking.error(e))    # If database is momentarily locked
            retry(times = 3)        # retry dbGetQuery(...) 3 more times
        else {
            # Handle other errors
        }
    }
)
6 Answers

A solution without pre-assigning values and using for instead of while:

some_function_that_may_fail <- function(i) {
  if( runif(1) < .5 ) stop()
  return(i)
}

for(i in 1:10){
  try({
    r <- some_function_that_may_fail(i)
    break #break/exit the for-loop
  }, silent = FALSE)
}

r will be equal to the number of tries that were needed. If you dont want the output of the errors set silent to TRUE

I have put together the code and make it package: retry

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

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

I like setting my object as an error from the start, also sometimes useful to add some sleep time if you're having connection problems:

res <- simpleError("Fake error to start")
counter <- 1
max_tries <- 10 
# Sys.sleep(2*counter)
while(inherits(res, "error") & counter < max_tries) { 
  res <- tryCatch({ your_fun(...) }, 
      error = function(e) e)
  counter <- counter + 1
}
Related