Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queries.R добавить события в обработчик ошибок - предложение #24

Open
yurasik2000 opened this issue Jun 11, 2017 · 5 comments

Comments

@yurasik2000
Copy link

Есть предложение - если POST запрос вернул чисто сетевую ошибку, например, "Error in open.connection(con, "rb") : Couldn't connect to server", то запрос необходимо повторить несколько раз, а уже потом выдавать ошибку и останавливать скрипт.

Часто такое бывает, что запрос не отрабатывает по техническим причинам (загруженность серверов, потери пакетов и т.д.) Неудобно, что из-за такой мелочи останавливается весь скрипт, и его надо перезапускать руками.

@Dementiy
Copy link
Owner

Dementiy commented Jun 11, 2017

Повтор запросов реализован в функции repeat_last_query (см. queries.R). Пока можно попробовать с ней поэкспериментировать.

Сколько раз должен повторяться запрос? Через какие промежутки времени? И на какие сетевые ошибки мы должны повторять запрос?

Если есть возможность собирать пакет локально, то можно пока поэкспериментировать с такой функцией execute (при любой ошибке не от API ВК, ждем одну секунду и повторяем запрос):

execute <- function(code, params = list()) {
  request_delay()
  query <- "https://api.vk.com/method/execute"
  body = list('code' = code, 'access_token' = getAccessToken())
  safe_POST <- purrr::safely(httr::POST)
  post_res <- safe_POST(url = query, body = append(body, params))

  if (!is.null(post_res$error)) {
    Sys.sleep(1.0)
    return(repeat_last_query(n=1))
  }

  post_res <- post_res$result
  content <- httr::content(post_res, "text", encoding="UTF-8")
  if (startsWith(content, "ERROR"))
    vk_stop(message = sprintf("Response error '%s'", content),
            error_code = post_res$status_code)

  response <- jsonlite::fromJSON(content)

  if (has_error(response)) {
    return(try_handle_error(response))
  }

  response$response
}

Для ее работы нужен пакет purrr. И есть вероятность бесконечной рекурсии, так как нет ограничения на число повторных запросов.

@Dementiy
Copy link
Owner

Dementiy commented Jun 11, 2017

На текущий момент сделано так: по умолчанию происходит три повторных запроса с интервалом в три секунды. Эти параметры можно изменить с помощью функций setTimeout(N) (таймаут в N секунд перед новым запросом) и setRepeats(N) (сделать N повторных запросов). Также появилась зависимость от пакета purrr.
Я проверял работоспособность следующим образом: отключал сеть и пытался выполнить запрос:

> setTimeout(1)
> setRepeats(10)
> wall <- getWallExecute(domain='spbrug')
Warning: Couldn't resolve host name
Warning: Trying to repeat the last query...
Warning: Couldn't resolve host name
Warning: Trying to repeat the last query...
Warning: Couldn't resolve host name
Warning: Trying to repeat the last query...

За это время поднимал сеть обратно. Couldn't resolve host name ошибка, которая возникает при запросе (в данном случае - нет сетевого соединения). Trying to repeat the last query... сообщение о том, что происходит попытка выполнить повторный запрос.

P.S. Такой обработчик добавлен только для методов, которые работают через execute().

@yurasik2000
Copy link
Author

@Dementiy, спасибо за доработку.
Да, метод перезапускается при сетевых ошибках.

Но пару раз ловилась такая ошибка в getGroupsMembersExecute, error и, соответственно, остановка скрипта.

Warning: Failure when receiving data from the peer
Warning: Trying to repeat the last query...
Error in do.call(what = gsub("\\(.*\\)", "", parent_name), args = args) : 
  'what' must be a function or character string

@Dementiy Dementiy reopened this Jun 20, 2017
@Dementiy
Copy link
Owner

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

@yurasik2000
Copy link
Author

@Dementiy, к сожалению, случай невоспроизводимый однозначно. При перезапуске метода ошибка пропадает. Видимо она случается, когда из api получаются неполные/оборванные данные. Если я ее поймаю еще раз, как мне ее отбэктрейсить?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants