Hao Ye
Hao Ye

Reputation: 205

Specify the calling function for an error message in R

I'm working on an R package where the same input-checking functions are called by multiple "actual" functions that are exported to users. If I use a simple stop() call, the error message is going to say that an error occurred in the input-checking function, which is not that useful...

I thought I'd get around this by wrapping the call to the input-checking function inside a tryCatch(), and then handling the error in the outer function. This does mostly what I want, but doesn't quite give the output that I'd like. The closest I've come is the following:

f <- function(i) {
    tryCatch({
        check_input(i)
    }, error = function(e) stop("in f: ", e$message, call. = FALSE)
    )
}

check_input <- function(i) {
    if(i < 0)
        stop("i is negative, value given was ", i)
}

f(-1)
# Error: in f: i is negative, value given was -1

Ideally, I'd like the error message to be

Error in f: i is negative, value given was -1

, which would be the case if stop were called within f() instead of check_input().

Upvotes: 3

Views: 725

Answers (1)

MrFlick
MrFlick

Reputation: 206232

Here's how you can grab the name of the function from the call stack and paste it in to the error message

f <- function(i) {
  check_input(i)
}
g <- function(i) {
  check_input(i)
}

check_input <- function(i, from=deparse(sys.calls()[[sys.nframe()-1]][[1]])) {
  getmsg <- function(m) ifelse(!is.null(from), paste0("in ", from, ": ", m), m)
  if(i < 0)
    stop(getmsg(paste0("i is negative, value given was ", i)), call. = FALSE)
}

f(-1)
#  Error: in f: i is negative, value given was -1
g(-1)
#  Error: in g: i is negative, value given was -1

You could also call check_input(i, from="otherfunction") to show whatever function name you want or check_input(i, from=NULL) to suppress the function name.

Upvotes: 2

Related Questions