Custom Errors in R Programming Language

# A custom error type usually has the suffix "Error".
argError <- function(arg, message) {
  structure(list(arg = arg, message = message), class = "argError")
}

# Adding this Error method makes argError implement
# the error interface.
print.argError <- function(x, ...) {
  cat(sprintf("%d - %s", x$arg, x$message))
}

f <- function(arg) {
  if (arg == 42) {
    # Return our custom error.
    return(list(value = -1, error = argError(arg, "can't work with it")))
  }
  list(value = arg + 3, error = NULL)
}

main <- function() {
  # tryCatch is R's equivalent to try-catch in other languages
  result <- tryCatch({
    f(42)
  }, error = function(e) {
    return(list(value = NULL, error = e))
  })
  
  if (!is.null(result$error) && inherits(result$error, "argError")) {
    cat(result$error$arg, "\n")
    cat(result$error$message, "\n")
  } else {
    cat("err doesn't match argError\n")
  }
}

main()

In R, we don’t have a built-in error system quite like Go’s, but we can achieve similar functionality using custom S3 classes and the tryCatch function.

  1. We define argError as a function that creates a list with arg and message fields, and assigns it the class “argError”.

  2. We define a custom print method for the argError class, which mimics the Error() method in the Go example.

  3. The f function is similar to the Go version, but it returns a list with value and error fields instead of using multiple return values.

  4. In the main function, we use tryCatch to handle potential errors. This is similar to Go’s error handling, but uses R’s exception mechanism.

  5. We check if the error is of class “argError” using inherits(), which is similar to the errors.As() function in Go.

When you run this script, it will output:

42
can't work with it

This R code demonstrates how to create and use custom error types, mirroring the functionality of the original Go example while using R’s idiomatic approaches to error handling and object-oriented programming.