23#ifndef Rcpp__exceptions__h
24#define Rcpp__exceptions__h
29#ifndef RCPP_DEFAULT_INCLUDE_CALL
30#define RCPP_DEFAULT_INCLUDE_CALL true
33#define GET_STACKTRACE() R_NilValue
54 virtual const char*
what()
const throw() {
67 std::ostringstream ostr;
75 message(std::string(
"no such environment: '") + name +
"'") {};
79 virtual const char*
what()
const throw() {
return message.c_str(); };
93 virtual const char*
what()
const throw() {
return message.c_str(); };
116 ::Rf_warning(
"%s",
message.c_str());
129 SEXP sentinel = PROTECT(Rf_allocVector(VECSXP, 1));
130 SET_VECTOR_ELT(sentinel, 0, token);
132 SEXP sentinelClass = PROTECT(Rf_mkString(
"Rcpp:longjumpSentinel"));
133 Rf_setAttrib(sentinel, R_ClassSymbol, sentinelClass) ;
141 Rf_inherits(x,
"Rcpp:longjumpSentinel") &&
142 TYPEOF(x) == VECSXP &&
147 return VECTOR_ELT(sentinel, 0);
154 ::R_ReleaseObject(token);
155 ::R_ContinueUnwind(token);
156 Rf_error(
"Internal error: Rcpp longjump failed to resume");
173 #define RCPP_ADVANCED_EXCEPTION_CLASS(__CLASS__, __WHAT__) \
174 class __CLASS__ : public std::exception { \
176 __CLASS__( ) throw() : message( std::string(__WHAT__) + "." ){} \
177 __CLASS__( const std::string& message ) throw() : \
178 message( std::string(__WHAT__) + ": " + message + "."){} \
179 template <typename... Args> \
180 __CLASS__( const char* fmt, Args&&... args ) throw() : \
181 message( tfm::format(fmt, std::forward<Args>(args)... ) ){} \
182 virtual ~__CLASS__() throw(){} \
183 virtual const char* what() const throw() { return message.c_str(); } \
185 std::string message; \
188 template <
typename... Args>
189 inline void warning(
const char* fmt, Args&&... args ) {
197 const std::string msg =
tfm::format(fmt, std::forward<Args>(args)...);
198 std::snprintf(buf,
sizeof(buf),
"%s", msg.c_str());
200 Rf_warning(
"%s", buf);
203 template <
typename... Args>
204 inline void NORET stop(
const char* fmt, Args&&... args) {
208 #define RCPP_EXCEPTION_CLASS(__CLASS__,__WHAT__) \
209 class __CLASS__ : public std::exception{ \
211 __CLASS__( ) throw() : message( std::string(__WHAT__) + "." ){} ; \
212 __CLASS__( const std::string& message ) throw() : \
213 message( std::string(__WHAT__) + ": " + message + "." ){} ; \
214 virtual ~__CLASS__() throw(){} ; \
215 virtual const char* what() const throw() { return message.c_str() ; } \
217 std::string message ; \
220 #define RCPP_SIMPLE_EXCEPTION_CLASS(__CLASS__,__MESSAGE__) \
221 class __CLASS__ : public std::exception{ \
223 __CLASS__() throw() {} ; \
224 virtual ~__CLASS__() throw(){} ; \
225 virtual const char* what() const throw() { return __MESSAGE__ ; } \
255 #undef RCPP_SIMPLE_EXCEPTION_CLASS
256 #undef RCPP_EXCEPTION_CLASS
257 #undef RCPP_ADVANCED_EXCEPTION_CLASS
262 inline SEXP
nth(SEXP s,
int n) {
263 return Rf_length(s) > n ? (n == 0 ? CAR(s) : CAR(Rf_nthcdr(s, n))) : R_NilValue;
270 SEXP sys_calls_symbol = Rf_install(
"sys.calls");
271 SEXP identity_symbol = Rf_install(
"identity");
272 Shield<SEXP> identity_fun(Rf_findFun(identity_symbol, R_BaseEnv));
273 SEXP tryCatch_symbol = Rf_install(
"tryCatch");
274 SEXP evalq_symbol = Rf_install(
"evalq");
276 return TYPEOF(expr) == LANGSXP &&
277 Rf_length(expr) == 4 &&
278 nth(expr, 0) == tryCatch_symbol &&
279 CAR(
nth(expr, 1)) == evalq_symbol &&
280 CAR(
nth(
nth(expr, 1), 1)) == sys_calls_symbol &&
281 nth(
nth(expr, 1), 2) == R_GlobalEnv &&
282 nth(expr, 2) == identity_fun &&
283 nth(expr, 3) == identity_fun;
290 SEXP sys_calls_symbol = Rf_install(
"sys.calls");
297 while(CDR(cur) != R_NilValue) {
298 SEXP expr = CAR(cur);
312 #ifndef RCPP_USING_UTF8_ERROR_STRING
313 SET_STRING_ELT( res, 0, Rf_mkChar( ex_class.c_str() ) ) ;
315 SET_STRING_ELT( res, 0, Rf_mkCharLenCE( ex_class.c_str(), ex_class.size(), CE_UTF8 ) );
317 SET_STRING_ELT( res, 1, Rf_mkChar(
"C++Error" ) ) ;
318 SET_STRING_ELT( res, 2, Rf_mkChar(
"error" ) ) ;
319 SET_STRING_ELT( res, 3, Rf_mkChar(
"condition" ) ) ;
323inline SEXP
make_condition(
const std::string& ex_msg, SEXP call, SEXP cppstack, SEXP classes){
325 #ifndef RCPP_USING_UTF8_ERROR_STRING
326 SET_VECTOR_ELT( res, 0, Rf_mkString( ex_msg.c_str() ) ) ;
329 SET_STRING_ELT( ex_msg_rstring, 0, Rf_mkCharLenCE( ex_msg.c_str(), ex_msg.size(), CE_UTF8 ) );
330 SET_VECTOR_ELT( res, 0, ex_msg_rstring ) ;
332 SET_VECTOR_ELT( res, 1, call ) ;
333 SET_VECTOR_ELT( res, 2, cppstack ) ;
336 SET_STRING_ELT( names, 0, Rf_mkChar(
"message" ) ) ;
337 SET_STRING_ELT( names, 1, Rf_mkChar(
"call" ) ) ;
338 SET_STRING_ELT( names, 2, Rf_mkChar(
"cppstack" ) ) ;
339 Rf_setAttrib( res, R_NamesSymbol, names ) ;
340 Rf_setAttrib( res, R_ClassSymbol, classes ) ;
344template <
typename Exception>
347 std::string ex_class =
demangle(
typeid(ex).name() ) ;
349 std::string ex_class =
"<not available>";
351 std::string ex_msg = ex.what() ;
360 cppstack = R_NilValue;
363 SEXP condition = shelter(
make_condition( ex_msg, call, cppstack, classes) );
378 using namespace Rcpp;
380 #ifndef RCPP_USING_UTF8_ERROR_STRING
386 SET_STRING_ELT( tryError, 0, Rf_mkCharLenCE( str.c_str(), str.size(), CE_UTF8 ) );
387 Rcpp::Shield<SEXP> simpleErrorExpr( Rf_lang2(::Rf_install(
"simpleError"), tryError ));
391 Rf_setAttrib( tryError, R_ClassSymbol, Rf_mkString(
"try-error") ) ;
392 Rf_setAttrib( tryError, Rf_install(
"condition") , simpleError ) ;
401std::string
demangle(
const std::string& name) ;
403#define DEMANGLE(__TYPE__) demangle( typeid(__TYPE__).name() ).c_str()
408 SEXP stop_sym = Rf_install(
"stop" ) ;
411 Rf_eval( expr, R_GlobalEnv ) ;
415 SEXP stop_sym = Rf_install(
"stop" ) ;
418 Rf_eval( expr, R_GlobalEnv ) ;
std::vector< std::string > stack
void copy_stack_trace_to_r() const
exception(const char *message_, bool include_call=RCPP_DEFAULT_INCLUDE_CALL)
bool include_call() const
void record_stack_trace()
exception(const char *message_, const char *, int, bool include_call=RCPP_DEFAULT_INCLUDE_CALL)
virtual const char * what() const
file_exists(const std::string &file)
virtual const char * what() const
std::string filePath() const
file_io_error(const std::string &msg, const std::string &file)
file_io_error(int code, const std::string &file)
file_io_error(const std::string &file)
file_not_found(const std::string &file)
no_such_env(const std::string &name)
virtual const char * what() const
void forward_rcpp_exception_to_r(const Rcpp::exception &ex)
void forward_exception_to_r(const std::exception &ex)
SEXP exception_to_try_error(const std::exception &ex)
#define RCPP_EXCEPTION_CLASS(__CLASS__, __WHAT__)
std::string demangle(const std::string &name)
SEXP string_to_try_error(const std::string &str)
SEXP get_exception_classes(const std::string &ex_class)
SEXP rcpp_exception_to_r_condition(const Rcpp::exception &ex)
SEXP make_condition(const std::string &ex_msg, SEXP call, SEXP cppstack, SEXP classes)
SEXP exception_to_r_condition(const std::exception &ex)
#define RCPP_ADVANCED_EXCEPTION_CLASS(__CLASS__, __WHAT__)
#define RCPP_SIMPLE_EXCEPTION_CLASS(__CLASS__, __MESSAGE__)
SEXP exception_to_condition_template(const Exception &ex, bool include_call)
#define RCPP_DEFAULT_INCLUDE_CALL
internal implementation details
bool isLongjumpSentinel(SEXP x)
SEXP getLongjumpToken(SEXP sentinel)
void resumeJump(SEXP token)
bool is_Rcpp_eval_call(SEXP expr)
SEXP longjumpSentinel(SEXP token)
void NORET stop(const std::string &message)
static std::string toString(const int i)
void warning(const std::string &message)
attribute_hidden SEXP rcpp_set_stack_trace(SEXP e)
attribute_hidden SEXP rcpp_get_stack_trace()
LongjumpException(SEXP token_)