Функции и try() в R

По-прежнему борется с R, особенно при обработке ошибок:

Если я использую:

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

Я могу использовать:

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

проверить, что-то пошло не так. Нет проблем.

Но если я использую try в сочетании с функцией, он не работает так, как я ожидал:

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

дает "-1" для result и "integer" для class(result)

Так что я должен использовать

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

и используйте geterrmessage() для сообщения об ошибке?

Ответы

Ответ 1

Если вы внимательно прочитали сообщение об ошибке, вы увидите, что odbcConnect дает вам предупреждение. Ошибка генерируется драйверами ODBC, и это не ошибка в try значение (geterrmessage() тоже не будет работать).

Вы можете использовать tryCatch для обработки этого, например:

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

Еще несколько объяснений:
-1 является результатом функции odbcDriverConnect. Если вы посмотрите на код, есть строки

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

Итак, вы заканчиваете без ошибок (и с предупреждением) и с целым кодом от уровня C. На самом деле этот код возвращается, когда соединение также выполняется успешно (но тогда оно равно 1). Если ошибок нет, тогда класс результата не может быть try-error.
Это не проблема с try и функциями, но специфическими для этой конкретной функции (odbcDriverConnect).

Конечно, вы можете использовать это поведение, как в своем примере

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

С помощью tryCatch вы можете сделать

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

который создает переменную ch при успешном завершении и печатает сообщение при ошибке.
Или

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

который всегда создает переменную ch, но в случае отказа имеет значение NA.