DavisVaughan/furrr

furrr problem - managing tryCatch inside function of interest

Closed this issue · 4 comments

Hello,

I was running furrr::future_map() for different functions that manage tryCatch errors and I noticed a problem (I do not know if it will happen in the other furrr functions).

If the tryCatch function print the error as a message:

error = function(e){ message(e); return(NA) }

furrr::future_map() stops from that point. It cannot manage the error, but if you comment the message(e) then it works.

I attach a reproducible example:

lst <- list(1,2,3,-4,"a","b")

future::plan("multisession", workers = 2)

logFunction <- function(n){
  
  res <- tryCatch(
    expr = {
      exp(n)
    },
    # Specifying error message
    error = function(e){
      message(e) #if you comment this line works
      return(NA)
    }
  )
}

res_vector <- furrr::future_map(lst, ~logFunction(.))

Thanks for developing the furrr package.

Regards,
Pedro Salguero

I can reproduce this with future alone, so I think it is a future issue. @HenrikBengtsson I think it has to do with the way you "signal immediate conditions"? Not sure.

library(future)

plan(sequential)

x <- "b"

fn <- function(x) {
  tryCatch(
    expr = exp(x),
    error = function(e) {
      message(e)
      NA_real_
    }
  )
}

# message, with value
fn(x)
#> non-numeric argument to mathematical function
#> [1] NA


# error
fut <- future(fn(x))
value(fut)
#> Error in exp(x): non-numeric argument to mathematical function

In the meantime, @psalguerog if you just do message(e$message) rather than message(e), it will work:

lst <- list(1,2,3,-4,"a","b")

future::plan("multisession", workers = 2)

logFunction <- function(n){
  
  res <- tryCatch(
    expr = {
      exp(n)
    },
    # Specifying error message
    error = function(e){
      message(e$message)
      return(NA)
    }
  )
}

res_vector <- furrr::future_map(lst, ~logFunction(.))
#> non-numeric argument to mathematical function
#> non-numeric argument to mathematical function
res_vector
#> [[1]]
#> [1] 2.718282
#> 
#> [[2]]
#> [1] 7.389056
#> 
#> [[3]]
#> [1] 20.08554
#> 
#> [[4]]
#> [1] 0.01831564
#> 
#> [[5]]
#> [1] NA
#> 
#> [[6]]
#> [1] NA

Created on 2022-03-01 by the reprex package (v2.0.1)

In the meantime, @psalguerog if you just do message(e$message) rather than message(e), it will work:

As @DavisVaughan concludes in HenrikBengtsson/future#596, there is probably nothing that come be done to prevent this behavior. It's not a bug in future. It's instead an unfortunate property of message(), and warning(), that cannot be worked around.

Also, as @DavisVaughan show in the future issue, it's probably better to use:

message(conditionMessage(e))

because I'm not sure/don't think the message field is part of the official API. Theoretically, I think it is valid of an error class to name it, say, msg. So, conditionMessage() is the safe bet.