From edd at debian.org  Thu Apr 16 04:14:24 2009
From: edd at debian.org (Dirk Eddelbuettel)
Date: Wed, 15 Apr 2009 21:14:24 -0500
Subject: [Rd] How can I catch errors thrown from c via the Rcpp
	error()	function?
In-Reply-To: <49E683EA.5060001@bccrc.ca>
References: <49E683EA.5060001@bccrc.ca>
Message-ID: <18918.38016.273317.952607@ron.nulle.part>


Kieran,

On 15 April 2009 at 18:03, Kieran O'Neill wrote:
| I am using the flowClust package from BioConductor, which is largely 
| implemented in c. For some of my data, the package occasionally (and 
| quite stochastically) encounters a particular condition which halts its 
| operation. At this point, it calls the error() function defined by Rcpp, 
| and halts.
| 
| What I would like to be able to do is to catch the error thrown, and 
| retry the operation a few times before giving up.
| 
| However, when I wrap the call to flowClust in try() or tryCatch(), the 
| error seems to completely bypass them:
| 
| Examples:
| 
| 1. This is a trivial example just to test the try() function, and 
| correctly assigns the error to the variable x:
| 
|  > x <- try(stop(simpleError('blah')))
| Error : blah
|  > x
| [1] "Error : blah\n"
| attr(,"class")
| [1] "try-error"
| 
| 2. This is an example using flowClust (using real data, set up to 
| guarantee that the error is thrown):
| 
|  > x <- try(res30 = flowClust(tFrame, K=30, B=1000, varNames=c('CD4', 
| 'CD8','KI67', 'CD45RO', 'CD28', 'CD57', 'CCR5', 'CD19', 'CD27', 'CCR7', 
| 'CD127')))
| Error in flowClust(tFrame, K = 30, B = 1000, varNames = c("CD4", "CD8",  :
| 
| The covariance matrix is near singular!
| Try running the program with a different initial configuration or less 
| clusters
|  > x
| Error: object "x" not found
| 
| 
| The c code throwing the error is as follows (from flowClust.c):
| 
| if(status!=0)
|    {
|        error("\n The covariance matrix is near singular! \n Try running 
| the program with a different initial configuration or less clusters 
| \n");          }
| 
| 
| I looked up the error() function in Writing R Extensions  and it states: 
| "The basic error handling routines are the equivalents of stop and 
| warning in R code, and use the same interface."
| 
| Yet, it seems that they are not caught by R's error handling code.
| 
| So:
| 
| 1. Is this the general case (that Rcpp error()s are not handled by try() 
| and related methods in R)? (I'm sure this could be tested with a trivial 
| example, but I'm not yet familiar enough with wrapping c code in R to do 
| so.)

Allow me to take the narrow view here as Rcpp maintainer.  What you can do
with Rcpp is to provide a C++ layer of try/catch around inner code which may
throw C++ exception.  This will usually be caught, and (as shown in the Rcpp
docs and examples) we can pass the exception message back up to R as a
regular error message.  This is very useful as it gives you control back at
the R prompt rather than just going belly-up.

Now, R's try() and tryCatch() are completely separate and not tied into the
exception mechanism Rcpp deals with, which is at a much lower level. 

Likewise, you may be out of luck with flowClust if it is C program.  You
could try to add a C++ layer that tried to catch error and allows you do
continue your loops.  I did something like that 15 years ago in my
dissertation research to ensure I survived the occassional numerical error
from Fortran during longer Monte Carlo runs,

| 2. If so, what is the correct way to handle them in R?

Tricky. See 1. :)

| 3. If not, do you have any suggestions as to what may have caused 
| flowClust to behave in this way? (So that I can contact the package 
| maintainers and report the bug.)

You could always contact them anyway and ask for advice.

Hth,  Dirk

-- 
Three out of two people have difficulties with fractions.



[Rd] How can I catch errors thrown from c via the Rcpp error() function?
Dirk Eddelbuettel