Как обработать ошибку API в цикле foreach R? - PullRequest
1 голос
/ 15 марта 2019

К вашему сведению, основываясь на некоторых комментариях, я добавил дополнительную информацию.

Я создал следующую функцию, которая выполняет вызов API:

keyword_checker <- function(keyword, domain, loc, lang){

  keyword_to_check <- as.character(keyword)

  api_request <- paste("https://script.google.com/blabalbalba",
                       "?kw=",keyword,
                       "&domain=",domain,
                       "&loc=",loc,
                       "&lang=",lang,sep="")
  api_request <- URLencode(api_request, repeated = TRUE)  
  source <-fromJSON(file = api_request)#Json file into Data Frame
  return(data.frame(do.call("rbind", source$data$result))) ##in order to extract only the "results" data

Я использую пакет R foreach() с %dopar% и doSNOW для выполнения многих вызовов API (более 120 000 вызовов).К сожалению, случается, что есть некоторые errors (обычно время ожидания соединения), поэтому скрипт останавливается.Чтобы избежать этой проблемы, я использовал .errorhandling = 'pass'.Теперь сценарий не останавливается, но я хотел бы знать, есть ли способ сделать вызов API, пока я не получу ответ?

Вот мой сценарий:

cl <- makeCluster(9)
registerDoSNOW(cl)

final_urls_checker <- foreach(i = 1:length(mes_urls_to_check), .combine=rbind, .errorhandling = 'pass', .packages='rjson') %dopar% {
  test_keyword <- as.character(mes_urls_to_check[i])
  results <- indexed_url(test_keyword)}  ##name of my function

##Stop cluster
stopCluster(cl)

Я в основном хочу, чтобы мой сценарий продолжался (без остановки всего процесса), пока я не получу ответ от вызова API

Нужно ли включать функцию TryCatch в foreach, ИЛИ что лучше«обновить» созданную мной функцию, добавив что-то вроде «если API не дает ответа, а затем подождать, пока оно не получит его?»

Надеюсь, это будет понятнее.

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Попробуйте использовать tryCatch внутри функции foreach, чтобы перехватить ожидаемые сообщения об ошибках (здесь произошел сбой вызова API из-за истечения времени ожидания). Ниже приведен пример кода для данной функции keyword_checker, основанный на моем понимании.

library(foreach)
 cl <- makeCluster(9)
registerDoSNOW(cl)

final_urls_checker <- foreach(i = 1:length(mes_urls_to_check), .combine=rbind, .errorhandling = 'pass', 
    .packages='rjson') %dopar% {
  test_keyword <- as.character(mes_urls_to_check[i])
  #results <- keyword_checker(test_keyword)}  ##name of my function
  results <- function(test_keyword){
    dmy <- tryCatch(
    {
        keyword_checker(test_keyword)
    },
    error = function(cond){
        message = "Timeout error! Calling again..."
        dmy2 <- keyword_checker(test_keyword)
        return(dmy2) 
    }
    warning = function(cond){
        message("Warning message:")
        message(cond)
        return(NULL)
    }
    finally = {
        message(paste("Succesfully called API ", test_keyword))
    }
        )
    return(dmy)
  }

##Stop cluster
stopCluster(cl)

Вот ссылка , которая объясняет, как писать tryCatch. Обратите внимание, этот фрагмент может не работать точно, так как я не запускал блок кода. Но при повторном вызове вызывающего API-интерфейса следует выполнить работу.

Проверьте эту ссылку , для обсуждения аналогичной проблемы.

1 голос
/ 18 марта 2019

Вот обновленный скрипт, включающий TryCatch непосредственно в функцию.

indexed_url <- function(url){

  url_to_check <- as.character(url)

  api_request <- paste("https://script.google.com/macros/blablabalbalbaexec",
                       "?page=",url_to_check,sep="")
  api_request <- URLencode(api_request, repeated = TRUE)  
  source <- tryCatch({
    fromJSON(file = api_request)#Convertir un Json file en Data Frame  
  }, error = function(e) {
    cat(paste0("Une erreur a eu lieu :",e))
    Sys.sleep(1)
    indexed_url(url)
  })  
  return(data.frame(do.call("rbind", source)))
}

Затем запустить foreach так, как было, работает отлично. Больше ошибок нет, и у меня есть полный анализ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...