I need to catch an error in Rf_eval
in C
. Is that even possible?
Some sample function
SEXP foo(SEXP x, SEXP env) {
SEXP res;
PROTECT(res = Rf_eval(x, env));
UNPROTECT(1);
return res;
}
I have tried Rcpp_eval
from Rcpp
and Rcpp11
, but both of them don't work for my case, I need to call Rf_eval
directly. Is it possible to catch an error directly in C? If so how?
use R_tryEval or R_tryEvalSilent in Rinternals.h
#include <Rdefines.h>
SEXP foo(SEXP fun, SEXP env)
{
int err = 0;
R_tryEval(fun, env, &err);
if (err)
Rprintf("error occurred\n");
return R_NilValue;
}
with
> .Call("foo", quote(stop("oops")), .GlobalEnv)
Error: oops
error occurred
NULL
Here's a little more complete example, retrieving the last error
#include <Rdefines.h>
SEXP silent(SEXP fun, SEXP env, SEXP errmsg)
{
int err = 0;
SEXP result = PROTECT(R_tryEvalSilent(fun, env, &err));
if (err) {
SEXP msg = PROTECT(R_tryEvalSilent(errmsg, env, &err));
if (!err)
Rprintf("error occurred: %s",
CHAR(STRING_ELT(msg, 0)));
else
Rprintf("(unknown) error occurred");
UNPROTECT(1);
result = R_NilValue;
}
UNPROTECT(1);
return result;
}
used as
.Call("silent", quote(stop("oops")), .GlobalEnv, quote(geterrmessage()))
Probably it makes a lot of sense to leave as much code as possible (e.g., conditional error handling) at the R level, either by wrapping the function to be evaluated or providing a custom error handling function instead of geterrmessage()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With