Home > Software engineering >  How Try and catch hierarchy works in R?
How Try and catch hierarchy works in R?

Time:10-14

I was wondering how try and catch hierarchy works in R.

I though that if I have a function that contains a try and catch, if there is an error there it is captured and the code can keep going. If you have a second function with a try and catch that in some point requires the first function, I though that if the first function finds and error, the error value will be returned so the second function will work considering the error value and it will not enter in the catch statement.

However, this does not work like this and it also enters in the second function error catch statement. I will try to simplify and put an example (although the functions make no sense)

The first function readUrl extracts the html output of an url if it exists, if not it returns NA. The second function executes the readUrl function and also a sum and it returns both elements in a list.

library(dplyr)

#Function 1

readUrl <- function(url){
  out <- tryCatch({
    message(paste0("Trying to enter the url: ", url))
    url <- rvest::read_html(url)
  },
  error = function(cond){
    message(paste("URL does not seem to exist: ", url))
    message("It has entered in the first function catch")
    message(cond)
    # Return value in case of error
    return(NA)
  },
  warning = function(cond){
    message(paste("URL caused a warning:", url))
    message("Here's the original warning message:")
    message(cond)
    return(NULL)
  }
  )
  return (out)
}


#function 2

func2 <- function (variant.id){
  
  output <- tryCatch({
    url1 <- paste0("https://www.ncbi.nlm.nih.gov/clinvar/variation/", variant.id)
    url.extract <- readUrl(url1)
    sum <- 2 2
    list(url = url.extract, sum = sum)
  },
  error = function(cond){
    message("It has entered in the second function Catch ")
    # Return value in case of error
    return(cond)
  },
  warning = function(cond){
    return(NULL)
  }
  )
  return (output)
}


#We enter a valid id It works fine
func2("579822")

#We enter an invalid id , it enters both try and Catch instead of only the first one
func2("579822G")

I was expecting the func2("579822G") output to be a list like this:

$url
NA
$sum
[1] 4

how can I handle these? I know this two functions don't make sense, but I do need to do something following this logic. Thanks in advance.

CodePudding user response:

message(cond) in the error handler for readUrl is what causes the wonky behavior. Replace it with print(cond) if you want to echo details of the exception before returning to the calling routine. This version works the way you expect it to:

readUrl <- function(url){
  out <- tryCatch({
    message(paste0("Trying to enter the url: ", url))
    url <- rvest::read_html(url)
  },
  error = function(cond){
    message(paste("URL does not seem to exist: ", url))
    message("It has entered in the first function catch")
    print(cond)
    # Return value in case of error
    return(NA)
  },
  warning = function(cond){
    message(paste("URL caused a warning:", url))
    message("Here's the original warning message:")
    print(cond)
    return(NULL)
  }
  )
  return (out)
}


#function 2

func2 <- function (variant.id){
  
  output <- tryCatch({
    url1 <- paste0("https://www.ncbi.nlm.nih.gov/clinvar/variation/", variant.id)
    url.extract <- readUrl(url1)
    sum <- 2 2
    list(url = url.extract, sum = sum)
  },
  error = function(cond){
    message("It has entered in the second function Catch ")
    # Return value in case of error
    return(cond)
  },
  warning = function(cond){
    return(NULL)
  }
  )
  return (output)
}


#We enter a valid id It works fine
func2("579822")

#We enter an invalid id , it enters both try and Catch instead of only the first one
func2("579822G")
  • Related