16

Still struggling with R, especially with error handling:

If I use:

result <- try(sqlSave(ch,df,tablename="tblTest"))

I can use:

if (class(result) != "try-error")

to check if something went wrong. No problem.

But if I use try in combination with a function it doesn't work as I expected:

 result <- try(ch<-odbcConnect("TEST"))

gives "-1" for result and "integer" for class(result)

So should I use

ch<-odbcConnect("TEST")
if (ch != -1)

and use geterrmessage() for the error message?

rcs
  • 67,191
  • 22
  • 172
  • 153
waanders
  • 8,907
  • 22
  • 70
  • 102

1 Answers1

10

If you read closely error message you could see that odbcConnect gives you warning. Error is generated by ODBC drivers and it isn't error in try meaning (geterrmessage() won't work either).

You could use tryCatch to handle this, e.g.:

tryCatch(odbcConnect("TEST"), warning=function(w) print("FAIL!"))

Some more explanation:
-1 is a result of odbcDriverConnect function. If you look at the code there are lines

stat <- .Call(C_RODBCDriverConnect, as.character(connection), 
        id, as.integer(believeNRows), as.logical(readOnlyOptimize))
if (stat < 0L) {
     warning("ODBC connection failed")
     return(stat)
}

So you end without errors (and with a warning) and with integer code from C-level. Actually this code is returned when connection is succeed too (but then is equal 1). When there is no errors then result class can't be try-error.
It is not problem with try and functions but specific of this particular function (odbcDriverConnect).

You could of course use this behaviour as in your example

ch <- odbcConnect("TEST")
if (ch != -1)

With tryCatch you could do

tryCatch(ch<-odbcConnect("TEST"), warning=function(w) print("FAIL!"))

which creates ch variable when succeed and print message when failed.
Or

ch <- tryCatch(odbcConnect("TEST"), warning=function(w) {print("FAIL!");return(NA)})

which always creates ch variable but in case of failure there is NA value.

Marek
  • 49,472
  • 15
  • 99
  • 121
  • But still I don't understand why class(result) give "integer" with a function call and otherwise "try-error". And where do I store the channel variable of odbcConnect in your example? – waanders Aug 09 '10 at 14:03
  • Just one question: Why doesn't -- df <- tryCatch(sqlQuery(ch,paste("SELECT * FROM tblTest")), warning=function(w) {print("FAIL!");return(NA)}) -- work the same? I don't get a printed warning and "df" contains the error message not a "NA" value – waanders Aug 10 '10 at 11:02
  • 2
    Cause in case of error you should write function to handle it. So you should do: `df <- tryCatch(sqlQuery(ch,paste("SELECT * FROM tblTest")),warning=function(w) {print("FAIL! (warning)");return(NA)},error=function(e) {print("FAIL! (error)");return(NA)})` – Marek Aug 10 '10 at 11:10
  • Still no printed error message. Something to do with "options" or something? – waanders Aug 10 '10 at 11:53
  • 1
    Change `error` function to print message if you want this: `error=function(e) {print(geterrormessage());print("FAIL! (error)");return(NA)}`. – Marek Aug 10 '10 at 14:19
  • I've now two pieces of code: `ch <- tryCatch(odbcConnect("TEST"), warning=function(w) {print("FAIL! (warning)");return(NA)}, error=function(e) {print(paste("ERROR:",geterrmessage()));return(NA)})` and `df <- tryCatch(sqlQuery(ch,"SELECT * FROM tblTest"), warning=function(w) {print("FAIL! (warning)");return(NA)}, error=function(e) {print(paste("ERROR:",geterrmessage()));return(NA)})`. odbcConnect works fine with errors and warnings, sqlQuery only with errors :-( – waanders Aug 10 '10 at 15:11
  • I'll ask a separate question about this – waanders Aug 17 '10 at 10:36
  • So `try` doesn't catch warnings? Then how do you catch warnings? – isomorphismes Nov 08 '11 at 08:49