Search code examples
javamysqlrjrirjdbc

JRI - How locate Errors in R


So basically, I am using Java, JRI (R for Java) and RJDBC (with the help of JRI), which all work out pretty well. Now, I want to make my program as foolproof as possible. Let's say, that the string SQL_command is some kind of rubbish and not really a valid SQL-statement. In that case...

    re.eval("sql_data <- dbGetQuery(conn, \"" + SQL_command + "\")");

...should go wrong. My thinking goes like this: If that R command fails, there will be some kind of output in R. If everythings correct, no output. But how can I capture that possible output?

Keep in mind, that my problem is more about how to catch invalid R statements, so any other suggestion for a possible solution is also appreciated. The R output is not necessarily important, but it may be interesting anyway.

Thanks in advance!


Solution

  • I'd suggest to catch the (possible) exceptions due to R code directly in R. So, if I suspect that a command could give an error, I'd use the try function in R. Something along this lines:

           REXP y = re.eval("sql_data <- try(dbGetQuery(conn, \"" + SQL_command + "\"),silent=TRUE)");
           REXP x = re.eval("class(sql_data)");
           if ((x.asString()).equals("try-error")) {
              System.out.println(y.asString());
              // do something to catch the exception
           } else {
             // do normal stuff
           }
    

    In this way you can also display the R error.

    Here a little reproducible (aside from the database credentials) code that tries to execute first the valid query statement and then the invalid one.

          import java.io.*;
          import org.rosuda.JRI.*;
          public class Prova {
             public static void main(String[] args) {
               String[] commands = {"a<-try(dbGetQuery(conn,'show tables'))","a<-try(dbGetQuery(conn,'SS'))"};
               Rengine re=new Rengine (new String [] {"--vanilla"}, false, null);
               re.eval("require(RMySQL)");
               re.eval("conn<-dbConnect(MySQL(),user='xxx',password='xxx',dbname='xxx')");
               for (int i=0;i<2;i++) {
                 REXP y = re.eval(commands[i]);
                 REXP x = re.eval("class(a)");
                 if ((x.asString()).equals("try-error")) {
                   System.out.println(y.asString());
                 } else {
                   System.out.println(x.asString());
                 }
               }
               re.end();
             }
          }
    

    The output:

       data.frame
       Error in mysqlExecStatement(conn, statement, ...) : 
         RS-DBI driver: (could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SS' at line 1)