From wdunlap at tibco.com  Thu Apr 16 17:49:22 2009
From: wdunlap at tibco.com (William Dunlap)
Date: Thu, 16 Apr 2009 08:49:22 -0700
Subject: [Rd] How can I catch errors thrown from c via the
	Rcpperror()	function?
In-Reply-To: <18918.38016.273317.952607@ron.nulle.part>
References: <49E683EA.5060001@bccrc.ca>
	<18918.38016.273317.952607@ron.nulle.part>
Message-ID: <77EB52C6DD32BA4D87471DCD70C8D70001075F7A@NA-PA-VBE03.na.tibco.com>

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?
William Dunlap