From koneill at bccrc.ca  Thu Apr 16 20:50:59 2009
From: koneill at bccrc.ca (Kieran O'Neill)
Date: Thu, 16 Apr 2009 11:50:59 -0700
Subject: [Rd] How can I catch errors thrown from c via the Rcpperror()
 function?
In-Reply-To: <77EB52C6DD32BA4D87471DCD70C8D70001075F7A@NA-PA-VBE03.na.tibco.com>
References: <49E683EA.5060001@bccrc.ca>
	<18918.38016.273317.952607@ron.nulle.part>
	<77EB52C6DD32BA4D87471DCD70C8D70001075F7A@NA-PA-VBE03.na.tibco.com>
Message-ID: <49E77E13.2060602@bccrc.ca>

Hi all, and thanks for the responses.

As per Bill's suggestion, I tried:

x <- try(flowClust(tFrame, K=30, B=1000, varNames=c('CD4', 'CD8','KI67', 
'CD45RO', 'CD28', 'CD57', 'CCR5', 'CD19','CD27', 'CCR7','CD127')), 
silent=TRUE)

and it caught the error.

Indeed,

 x <- try(res30 <- flowClust(tFrame, K=30, B=1000, varNames=c('CD4', 
'CD8','KI67', 'CD45RO', 'CD28', 'CD57', 'CCR5', 'CD19','CD27', 
'CCR7','CD127')), silent=TRUE)

caught the error. (What I really meant by "res30 = flowClust(...)" was 
"res30 <- flowClust(...)". I've fallen into the probably bad habit of 
using '=' in place of '<-' ) It had completely slipped my mind that '=' 
has a dual meaning, and that using it there might result in that part of 
my expression being evaluated as the passing of an argument.

Anyway, the point is that it works, and the error is caught when I use '<-'.

Thanks again for all your help (and an interesting peek into the nuts 
and bolts of R).

-Kieran

William Dunlap wrote:
> Note that Kieren's example labelled the first
> argument to try() with an improper label res30=,
> not expr= (or is that a mailer turning something
> into '30='?).  If it really is an improper argument
> tag then this could be showing a buglet in reporting
> on wrongly named arguments:
>
>   > invisible(rm(x,y))
>   > x<-try(silent=TRUE, badTag=stop("Oops"))
>   Error in try(silent = TRUE, badTag = stop("Oops")) : Oops
>   > x
>   Error: object "x" not found
>   > y<-try(silent=TRUE, expr=stop("Oops"))
>   > y
>   [1] "Error in try(silent = TRUE, expr = stop(\"Oops\")) : Oops\n"
>   attr(,"class")
>   [1] "try-error"
>
> In the first example I would expect an error message like
>    unused argument(s) (badTag = stop("Oops"))
> but it is appropriate that try() would abort if it
> is called in a bad way.  Perhaps it is trying to make that
> error message and that triggered the evaluation of the argument,
> as in
>    > grep(mypattern=stop("Oops"), "wxyz")
>    Error in grep(mypattern = stop("Oops"), "wxyz") : Oops
> where one might expect an error message regarding the wrongly
> named argument, as in:
>    > grep(mypattern="x", "wxyz")
>    Error in grep(mypattern = "x", "wxyz") : 
>      unused argument(s) (mypattern = "x")
>
> Bill Dunlap
> TIBCO Software Inc - Spotfire Division
> wdunlap tibco.com 
>
>   
>> -----Original Message-----
>> From: r-devel-bounces at r-project.org 
>> [mailto:r-devel-bounces at r-project.org] On Behalf Of Dirk Eddelbuettel
>> Sent: Wednesday, April 15, 2009 7:14 PM
>> To: Kieran O'Neill
>> Cc: r-devel at r-project.org
>> Subject: Re: [Rd] How can I catch errors thrown from c via 
>> the Rcpperror() function?
>>
>>
>> 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.
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>



[Rd] How can I catch errors thrown from c via the Rcpperror() function?
Kieran O'Neill