diff options
author | Oleg Morozenkov <omorozenkov@gmail.com> | 2023-07-02 11:23:16 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-02 11:23:16 +0300 |
commit | 019c557ecef3433be80421c9583684ac7c04666d (patch) | |
tree | 437653b6401fa8ee26d8028216fa4b96b521dfec | |
parent | 36a7f0798728482ddaaaecd5e86b64039d6d1175 (diff) |
Revert "Revert "Repeat the http request on fail""
-rw-r--r-- | include/tgbot/net/HttpClient.h | 18 | ||||
-rw-r--r-- | src/Api.cpp | 45 |
2 files changed, 50 insertions, 13 deletions
diff --git a/include/tgbot/net/HttpClient.h b/include/tgbot/net/HttpClient.h index aa82c0d..1f1b2a2 100644 --- a/include/tgbot/net/HttpClient.h +++ b/include/tgbot/net/HttpClient.h @@ -29,6 +29,24 @@ public: virtual std::string makeRequest(const Url& url, const std::vector<HttpReqArg>& args) const = 0; std::int32_t _timeout = 25; + + /** + * @brief Get the maximum number of makeRequest() retries before giving up and throwing an exception. + */ + virtual int getRequestMaxRetries() const { + return requestMaxRetries; + } + + /** + * @brief Get the makeRequest() backoff duration between retries, in seconds. + */ + virtual int getRequestBackoff() const { + return requestBackoff; + } + +private: + int requestMaxRetries = 3; + int requestBackoff = 1; }; } diff --git a/src/Api.cpp b/src/Api.cpp index 7bd9e64..f238a70 100644 --- a/src/Api.cpp +++ b/src/Api.cpp @@ -1,5 +1,8 @@ #include "tgbot/Api.h" +#include <chrono> +#include <thread> + namespace TgBot { Api::Api(std::string token, const HttpClient& httpClient, const std::string& url) @@ -2504,20 +2507,36 @@ boost::property_tree::ptree Api::sendRequest(const std::string& method, const st url += "/"; url += method; - std::string serverResponse = _httpClient.makeRequest(url, args); - if (!serverResponse.compare(0, 6, "<html>")) { - throw TgException("tgbot-cpp library have got html page instead of json response. Maybe you entered wrong bot token."); - } - - boost::property_tree::ptree result = _tgTypeParser.parseJson(serverResponse); - try { - if (result.get<bool>("ok", false)) { - return result.get_child("result"); - } else { - throw TgException(result.get("description", "")); + int requestRetryBackoff = _httpClient.getRequestBackoff(); + int retries = 0; + while (1) + { + try { + std::string serverResponse = _httpClient.makeRequest(url, args); + if (!serverResponse.compare(0, 6, "<html>")) { + throw TgException("tgbot-cpp library have got html page instead of json response. Maybe you entered wrong bot token."); + } + + boost::property_tree::ptree result = _tgTypeParser.parseJson(serverResponse); + try { + if (result.get<bool>("ok", false)) { + return result.get_child("result"); + } else { + throw TgException(result.get("description", "")); + } + } catch (boost::property_tree::ptree_error& e) { + throw TgException("tgbot-cpp library can't parse json response. " + std::string(e.what())); + } + } catch (...) { + int max_retries = _httpClient.getRequestMaxRetries(); + if ((max_retries >= 0) && (retries == max_retries)) { + throw; + } else { + std::this_thread::sleep_for(std::chrono::seconds(requestRetryBackoff)); + retries++; + continue; + } } - } catch (boost::property_tree::ptree_error& e) { - throw TgException("tgbot-cpp library can't parse json response. " + std::string(e.what())); } } } |