tryCatch() Function in R

The tryCatch() function acts as a mechanism for handling errors and other conditions (like warnings or messages) that arise during code execution in R. It allows you to define custom behaviors when an error occurs instead of stopping the execution of the script.

The tryCatch() function lets you define custom handlers for four conditions. Each handler is a function taking a single argument—an object of class “condition” (e.g. e, w, or m). Each code block is the state of execution and the scope.

For simple error handling, you can use the only try() function because tryCatch() sometimes makes it complicated to handle very simple errors.

Syntax

result = tryCatch({
  expression
}, warning = function(w) {
  warning-handler-code
}, error = function(e) {
  error-handler-code
}, finally = {
  cleanup-code
}

Conditions

Name Value
expr It specifies the expression we want to evaluate.
error It is the message we should return in case of an error.
warning It is the message we should return in case of a warning.
finally It is the message we should return when the tryCatch() function is finished.

Basic usage

non-numeric argument to mathematical function

Let’s find the log of the character value and analyze the output.

data <- log("ABC")

data

# Output
# Error in log("ABC") : non-numeric argument to mathematical function Execution halted

Maybe you’d want something to happen when such an error occurs.

Let’s handle this type of error:

Usage of tryCatch() function

tryCatch(log("ABC"),
 error = function(e)
 print("You can't calculate the log of a character"))

# Output: [1] "You can't calculate the log of a character"

In some cases, the specific return values (see a return(NA) above) can be specified by supplying a respective handler function (see arguments error and warning in ?tryCatch).

No error or warning occurs

What if we never get any error or warning? Well, in that case, the program runs smoothly and we get the desired output.

sqrt_and_divide <- function(x, y) {
  tryCatch(
  {
    result <- sqrt(x) / y
    return(result)
  },
  error = function(e) {
    message("An Error Occurred")
    print(e)
 },
 warning = function(w) {
   message("A Warning Occurred")
   print(w)
   return(NA)
  }
 )
}

sqrt_and_divide(4, 2)

# Output: [1] 1

An error occurred

What if the error occurs? In that case, the program will print the error to the console. You must investigate based on that error.

sqrt_and_divide <- function(x, y) {
  tryCatch(
  {
    result <- sqrt(x) / y
    return(result)
  },
  error = function(e) {
    message("An Error Occurred")
    print(e)
 },
 warning = function(w) {
   message("A Warning Occurred")
   print(w)
   return(NA)
  }
 )
}

sqrt_and_divide(4)

# Output: An Error Occurred

<simpleError in doTryCatch(return(expr), name, parentenv, handler): 
                          argument "y" is missing, with no default>

Handling a warning

What if the warning occurs? Well, if that is the case, then the warning message starts with Warning: “Something occurred”. Here, you can read the warning and investigate for yourself.

result <- tryCatch(
{
  log(-1) # This will generate a warning
},
 warning = function(w) {
   cat("Warning:", w$message, "\n")
   Inf # Return a specific value when a warning occurs
 }
)

# Output: Warning: NaNs produced

Finally Clause

The finally block is always executed regardless of whether an error has occurred or not, typically for cleaning up. It does not show any error or warning.

tryCatch({
  # Potentially error-prone code
}, error = function(e) {
  # Error handling code
}, finally = {
  # Clean-up code, runs whether or not there was an error
})

As suppressing all errors without proper handling can lead to code that fails silently, making debugging difficult.

Logging errors or taking specific actions when an error is caught is usually a good practice.

Leave a Comment