giraffehere
giraffehere

Reputation: 1148

Stopping Execution Of A Parent Function From Child In R

I'm using the stop function in R to make some troubleshooting measures. For example throwing an error when data was input wrong. I want a general function that I can call to do this checking, that I can then call in several different points of the parent code. I can throw an error just fine, however, I've noticed that the parent function keeps executing after the error is thrown and only my "error function" if you will stops executing. Is there a way to make R stop executing globally when an error from stop occurs?

Thank you.

A coded example of my issue:

StopCode <- function() {

  try(if(TRUE) stop("This try/if statement should stop the code from executing."))

}

StopCode() # This function should stop the code!

print("I should not see this statement if the try/if statement stopped the code in the way I desired.")

Console:

Error in try(if (TRUE) stop("This try/if statement should stop the code from executing.")) : 
  This try/if statement should stop the code from executing.
[1] "I should not see this statement if the try/if statement stopped the code in the way I desired."

The desired result should be that the StopCode function entirely stops the code instead of just the execution of the function. When you source this code, it stops the function, gives a warning and then proceeds to run the print function. I want that to not happen and for the stop in the function to kill the execution globally.

Upvotes: 2

Views: 743

Answers (2)

Konrad Rudolph
Konrad Rudolph

Reputation: 545518

By default, stop does exactly what you want it to do: it breaks out of every running function until it is at the top level — and, if the script is running non-interactively, it then stops the script.

However, in the code you’ve posted you explicitly tell R not to stop executing the calling function, by trapping the error via try. It’s unclear why you are using try here, since its only purpose is to prevent the behaviour that you seem to want.

The solution is simply to remove try from your code. Alternatively, you may want to trap the error, handle it, and then re-throw it:

result = try(‹some operation that may fail›)
if (inherits(result, 'try-error')) {
    ‹handle error›
    # Re-throw error:
    stop(attr(result, 'condition'))
}

Upvotes: 3

jimmyb
jimmyb

Reputation: 4387

Basically, you want to set options(error = ) to some function of your choosing. I'll paste the docs here ?options:

error:
either a function or an expression governing the handling of non-catastrophic
errors such as those generated by stop as well as by signals and internally
detected errors. If the option is a function, a call to that function, with
no arguments, is generated as the expression. The default value is NULL: see
stop for the behaviour in that case. The functions dump.frames and recover
provide alternatives that allow post-mortem debugging. Note that these need 
to specified as e.g. options(error = utils::recover) in startup files such
as ‘.Rprofile’.

Upvotes: 0

Related Questions