@@ -28,25 +28,33 @@ namespace Rcpp {
2828
2929 class exception : public std ::exception {
3030 public:
31- explicit exception (const char * message_) : message(message_) { // #nocov start
31+ explicit exception (const char * message_, bool include_call = true ) : // #nocov start
32+ message(message_),
33+ include_call_(include_call){
3234 rcpp_set_stack_trace (stack_trace ());
3335 }
34- exception (const char * message_, const char * file, int line) : message(message_) {
36+ exception (const char * message_, const char * file, int line, bool include_call = true ) :
37+ message (message_),
38+ include_call_ (include_call){
3539 rcpp_set_stack_trace (stack_trace (file,line));
3640 }
41+ bool include_call () const {
42+ return include_call_;
43+ }
3744 virtual ~exception () throw () {}
3845 virtual const char * what () const throw() {
3946 return message.c_str (); // #nocov end
4047 }
4148 private:
4249 std::string message;
50+ bool include_call_;
4351 };
4452
4553 // simple helper
4654 static std::string toString (const int i) { // #nocov start
4755 std::ostringstream ostr;
4856 ostr << i;
49- return ostr.str (); // #nocov end
57+ return ostr.str (); // #nocov end
5058 }
5159
5260 class no_such_env : public std ::exception {
@@ -127,7 +135,7 @@ namespace Rcpp {
127135 RCPP_EXCEPTION_CLASS (binding_is_locked, std::string(" binding is locked: '" ) + message + " '" )
128136 RCPP_EXCEPTION_CLASS (no_such_namespace, std::string(" no such namespace: '" ) + message + " '" )
129137 RCPP_EXCEPTION_CLASS (function_not_exported, std::string(" function not exported: " ) + message)
130- RCPP_EXCEPTION_CLASS (eval_error, message ) // #nocov end
138+ RCPP_EXCEPTION_CLASS (eval_error, message ) // #nocov end
131139
132140 #undef RCPP_EXCEPTION_CLASS
133141 #undef RCPP_SIMPLE_EXCEPTION_CLASS
@@ -217,6 +225,24 @@ inline SEXP make_condition(const std::string& ex_msg, SEXP call, SEXP cppstack,
217225 return res ;
218226}
219227
228+ inline SEXP rcpp_exception_to_r_condition (const Rcpp::exception& ex) {
229+ std::string ex_class = demangle ( typeid (ex).name () ) ;
230+ std::string ex_msg = ex.what () ;
231+
232+ SEXP call, cppstack;
233+ if (ex.include_call ()) {
234+ call = Rcpp::Shield<SEXP>(get_last_call ());
235+ cppstack = Rcpp::Shield<SEXP>( rcpp_get_stack_trace ());
236+ } else {
237+ call = R_NilValue;
238+ cppstack = R_NilValue;
239+ }
240+ Rcpp::Shield<SEXP> classes ( get_exception_classes (ex_class) );
241+ Rcpp::Shield<SEXP> condition ( make_condition ( ex_msg, call, cppstack, classes) );
242+ rcpp_set_stack_trace ( R_NilValue ) ;
243+ return condition ;
244+ }
245+
220246inline SEXP exception_to_r_condition ( const std::exception& ex){
221247 std::string ex_class = demangle ( typeid (ex).name () ) ;
222248 std::string ex_msg = ex.what () ;
@@ -245,7 +271,7 @@ inline SEXP string_to_try_error( const std::string& str){
245271 Rf_setAttrib ( tryError, R_ClassSymbol, Rf_mkString (" try-error" ) ) ;
246272 Rf_setAttrib ( tryError, Rf_install ( " condition" ) , simpleError ) ;
247273
248- return tryError; // #nocov end
274+ return tryError; // #nocov end
249275}
250276
251277inline SEXP exception_to_try_error ( const std::exception& ex){
@@ -313,7 +339,7 @@ namespace Rcpp{
313339
314340 inline void NORET stop (const std::string& message) { // #nocov start
315341 throw Rcpp::exception (message.c_str ());
316- } // #nocov end
342+ } // #nocov end
317343
318344 template <typename T1>
319345 inline void NORET stop (const char * fmt, const T1& arg1) {
@@ -366,7 +392,14 @@ namespace Rcpp{
366392 }
367393}
368394
369- inline void forward_exception_to_r ( const std::exception& ex){
395+ inline void forward_exception_to_r (const std::exception& ex){
396+ SEXP stop_sym = Rf_install ( " stop" ) ;
397+ Rcpp::Shield<SEXP> condition ( exception_to_r_condition (ex) );
398+ Rcpp::Shield<SEXP> expr ( Rf_lang2 ( stop_sym , condition ) ) ;
399+ Rf_eval ( expr, R_GlobalEnv ) ;
400+ }
401+
402+ inline void forward_rcpp_exception_to_r (const Rcpp::exception& ex) {
370403 SEXP stop_sym = Rf_install ( " stop" ) ;
371404 Rcpp::Shield<SEXP> condition ( exception_to_r_condition (ex) );
372405 Rcpp::Shield<SEXP> expr ( Rf_lang2 ( stop_sym , condition ) ) ;
0 commit comments