[Rcpp-devel] experimental handling of uncaught exceptions

Romain François francoisromain at free.fr
Mon Dec 28 12:22:36 CET 2009


Now we can grab the exception class and its message :

require(Rcpp)
require(inline)
funx <- cfunction(signature(), '
throw std::range_error("boom") ;
return R_NilValue ;
', Rcpp=TRUE, verbose=FALSE)
tryCatch(  funx(), "C++Error" = function(e){
         cat( sprintf( "C++ exception of class '%s' : %s\n", 
class(e)[1L], e$message  ) )
} )
# or using a direct handler
tryCatch(  funx(), "std::range_error" = function(e){
         cat( sprintf( "C++ exception of class '%s' : %s\n", 
class(e)[1L], e$message  ) )
} )
# just to check things carry on
print( rnorm(10) )



On 12/28/2009 11:31 AM, Romain François wrote:
> On 12/28/2009 10:58 AM, Romain François wrote:
>> On 12/27/2009 09:03 PM, Dirk Eddelbuettel wrote:
>>>
>>> On 27 December 2009 at 13:36, Dirk Eddelbuettel wrote:
>>> | On 27 December 2009 at 18:15, Romain François wrote:
>>> | | Hi,
>>> | |
>>> | | I've commited some code that aims at forwarding uncaught C++
>>> exceptions
>>> | | to R.
>>> | |
>>> | | For example :
>>> | |
>>> | | require( Rcpp)
>>> | | funx<- cfunction(signature(), '
>>> | | throw std::range_error("boom") ;
>>> | | return R_NilValue ;
>>> | | ', Rcpp=TRUE, verbose=FALSE)
>>> | | tryCatch( funx(), "C++Error" = function(e){
>>> | | print( "gotcha" )
>>> | | } )
>>> | | print( rnorm(10) )
>>> |
>>> | That's pretty crazy cool -- I'll have to try that.
>>>
>>> Can we get access to the string 'boom' at the R level?
>>
>> I am not sure. I think we cannot. I would also like to reach the class
>> of the exception "range_error" to bring direct handlers (once again the
>> idea is rJava inspired) but this does not seem possible.
>>
>> If C++ had reflection, then this would be possible;
>>
>> tryCatch( funx(), range_error = function(e){
>> # do something with the range error exception
>> } )
>>
>> This does not aim to replace explicit try/catch within the code, but it
>> prevents the R session from crashing if some exception is not caught.
>
> Some random browsing brings some hope here:
> - http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html
> -
> http://doc.infopac.ru/C,C++/libstdc++-html-USERS-3.3/vterminate_8cc-source.html
>
> Also learned about the abi namespace (which is supposed to be
> cross-compiler) which brings some level of demangling capabilities :
> - http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html
>
> Not sure what I want to make of this.
>
>>> That's how the
>>> existing C++-based try/catch ->  Rf_error() works.
>>
>> For this I thought that maybe we could have an "r_error" exception, with
>> an overloaded throw operator so that we would do :
>>
>> throw r_error( "boom" ) ;
>>
>>> Also, the onAttach trick won't work for other packages just including
>>> Rcpp.h
>>> et al and linking to libRcpp.{so,a}.
>>
>> These packages can just call "initUncaughtExceptionHandler" from their
>> C++ side, this is the only thing the .onAttach does.
>>
>> Now the mechanism calls back an R function that lives (and is not
>> exported from) the Rcpp namespace.
>>
>> uncaught_cpp_exception<- function( message = "uncaught C++ exception" ){
>> callstack<- sys.calls()
>> ncalls<- length(callstack)
>> call<- if( ncalls>  1L) callstack[[ ncalls - 1L ]] else match.call()
>> classes<- c( "C++Error", "error", "condition" )
>> condition<- structure(
>> list( message = message, call = call ),
>> class = classes )
>> stop( condition )
>> }
>>
>> Are there cases where the libRcpp.{so,a} is used but the Rcpp package is
>> not available ?
>>
>> We could have it all in C, but this leads to more complicated code. See
>> the file rJava.c attached for how Simon does it in rJava. (look between
>> hack and hack)
>>
>>> Dirk
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/IlMh : CPP package: exposing C++ objects
|- http://tr.im/HlX9 : new package : bibtex
`- http://tr.im/Gq7i : ohloh





More information about the Rcpp-devel mailing list