@@ -28,25 +28,33 @@ namespace Rcpp {
28
28
29
29
class exception : public std ::exception {
30
30
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){
32
34
rcpp_set_stack_trace (stack_trace ());
33
35
}
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){
35
39
rcpp_set_stack_trace (stack_trace (file,line));
36
40
}
41
+ bool include_call () const {
42
+ return include_call_;
43
+ }
37
44
virtual ~exception () throw () {}
38
45
virtual const char * what () const throw() {
39
46
return message.c_str (); // #nocov end
40
47
}
41
48
private:
42
49
std::string message;
50
+ bool include_call_;
43
51
};
44
52
45
53
// simple helper
46
54
static std::string toString (const int i) { // #nocov start
47
55
std::ostringstream ostr;
48
56
ostr << i;
49
- return ostr.str (); // #nocov end
57
+ return ostr.str (); // #nocov end
50
58
}
51
59
52
60
class no_such_env : public std ::exception {
@@ -127,7 +135,7 @@ namespace Rcpp {
127
135
RCPP_EXCEPTION_CLASS (binding_is_locked, std::string(" binding is locked: '" ) + message + " '" )
128
136
RCPP_EXCEPTION_CLASS (no_such_namespace, std::string(" no such namespace: '" ) + message + " '" )
129
137
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
131
139
132
140
#undef RCPP_EXCEPTION_CLASS
133
141
#undef RCPP_SIMPLE_EXCEPTION_CLASS
@@ -217,6 +225,24 @@ inline SEXP make_condition(const std::string& ex_msg, SEXP call, SEXP cppstack,
217
225
return res ;
218
226
}
219
227
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
+
220
246
inline SEXP exception_to_r_condition ( const std::exception& ex){
221
247
std::string ex_class = demangle ( typeid (ex).name () ) ;
222
248
std::string ex_msg = ex.what () ;
@@ -245,7 +271,7 @@ inline SEXP string_to_try_error( const std::string& str){
245
271
Rf_setAttrib ( tryError, R_ClassSymbol, Rf_mkString (" try-error" ) ) ;
246
272
Rf_setAttrib ( tryError, Rf_install ( " condition" ) , simpleError ) ;
247
273
248
- return tryError; // #nocov end
274
+ return tryError; // #nocov end
249
275
}
250
276
251
277
inline SEXP exception_to_try_error ( const std::exception& ex){
@@ -313,7 +339,7 @@ namespace Rcpp{
313
339
314
340
inline void NORET stop (const std::string& message) { // #nocov start
315
341
throw Rcpp::exception (message.c_str ());
316
- } // #nocov end
342
+ } // #nocov end
317
343
318
344
template <typename T1>
319
345
inline void NORET stop (const char * fmt, const T1& arg1) {
@@ -366,7 +392,14 @@ namespace Rcpp{
366
392
}
367
393
}
368
394
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) {
370
403
SEXP stop_sym = Rf_install ( " stop" ) ;
371
404
Rcpp::Shield<SEXP> condition ( exception_to_r_condition (ex) );
372
405
Rcpp::Shield<SEXP> expr ( Rf_lang2 ( stop_sym , condition ) ) ;
0 commit comments