|
@@ -3,6 +3,8 @@
|
|
|
#include <freertos/task.h>
|
|
|
#include <esp_log.h>
|
|
|
|
|
|
+#include "kbf/exception.h"
|
|
|
+#include "kbf/http/exception.h"
|
|
|
#include "kbf/macros.h"
|
|
|
|
|
|
using namespace kbf;
|
|
@@ -34,7 +36,7 @@ void http::Client::init() {
|
|
|
|
|
|
http::Client::~Client() {
|
|
|
ESP_LOGD(TAG, "~Client()");
|
|
|
- CHECK(esp_http_client_cleanup(handle));
|
|
|
+ CHECK_ABORT(esp_http_client_cleanup(handle));
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<kbf::http::Response>
|
|
@@ -62,7 +64,8 @@ http::Client::performRequest(const kbf::http::Method method, const std::string &
|
|
|
esp_http_client_set_header(handle, "Content-Type", "application/json");
|
|
|
esp_http_client_set_post_field(handle, body.c_str(), body.length());
|
|
|
} else {
|
|
|
- ESP_LOGW(TAG, "unhandled method: %d", method);
|
|
|
+ ESP_LOGE(TAG, "unhandled method: %d", method);
|
|
|
+ throw kbf::exception::KBFError("unknown HTTP method " + std::to_string(method));
|
|
|
}
|
|
|
|
|
|
if (headers) {
|
|
@@ -89,17 +92,38 @@ http::Client::performRequest(const kbf::http::Method method, const std::string &
|
|
|
} else if (err == ESP_OK) {
|
|
|
ESP_LOGD(TAG, "success");
|
|
|
return response;
|
|
|
- } else if (err == ESP_ERR_HTTP_FETCH_HEADER && !retry) {
|
|
|
- // TODO this will happen on timeout as well; perhaps set a retry limit in ctor / get / post?
|
|
|
- ESP_LOGW(TAG, "fetching headers failed, maybe the connection was dropped? retrying...");
|
|
|
+ } else if ((err == ESP_ERR_HTTP_FETCH_HEADER || err == ESP_FAIL)) {
|
|
|
+ // TODO happens on timeout and conn reset as well; can we distinguish between errors here properly?
|
|
|
+
|
|
|
+ if (retry) {
|
|
|
+ ESP_LOGE(TAG, "retry failed (%s)", esp_err_to_name(err));
|
|
|
+ throw exception::RequestError();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timeoutMs) {
|
|
|
+ ESP_LOGE(TAG, "request failed (%s), assuming timeout", esp_err_to_name(err));
|
|
|
+ throw exception::Timeout();
|
|
|
+ }
|
|
|
+
|
|
|
+ ESP_LOGW(TAG, "request failed (%s), maybe the connection was dropped? retrying...", esp_err_to_name(err));
|
|
|
retry = true;
|
|
|
esp_http_client_cleanup(handle);
|
|
|
init();
|
|
|
- return get(url);
|
|
|
+ if (method == http::GET) {
|
|
|
+ return get(url, headers);
|
|
|
+ } else if (method == http::POST) {
|
|
|
+ return post(url, *postData, headers);
|
|
|
+ } else {
|
|
|
+ throw kbf::exception::KBFError("unknown HTTP method " + std::to_string(method));
|
|
|
+ }
|
|
|
+ } else if (err == ESP_ERR_HTTP_CONNECT) {
|
|
|
+ ESP_LOGW(TAG, "HTTP request failed: %s", esp_err_to_name(err));
|
|
|
+ running = false;
|
|
|
+ throw exception::ConnectionError();
|
|
|
} else {
|
|
|
- ESP_LOGE(TAG, "HTTP GET failed: %s", esp_err_to_name(err));
|
|
|
- if (onError) onError(*this);
|
|
|
- return nullptr;
|
|
|
+ ESP_LOGE(TAG, "unhandled HTTP error: %s", esp_err_to_name(err));
|
|
|
+ running = false;
|
|
|
+ throw kbf::exception::KBFError("unhandled HTTP error: %s" + string(esp_err_to_name(err)));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -108,11 +132,10 @@ esp_err_t http::Client::handleHttpEvent(esp_http_client_event_t *event) {
|
|
|
|
|
|
switch (event->event_id) {
|
|
|
case HTTP_EVENT_ERROR:
|
|
|
- ESP_LOGW(TAG, "fixme: unhandled error event: HTTP_EVENT_ERROR");
|
|
|
- if (client->onError) client->onError(*client);
|
|
|
+ ESP_LOGE(TAG, "fixme: unhandled error event: HTTP_EVENT_ERROR");
|
|
|
client->running = false;
|
|
|
client->retry = false;
|
|
|
- break;
|
|
|
+ throw kbf::exception::KBFError("HTTP_EVENT_ERROR");
|
|
|
case HTTP_EVENT_ON_CONNECTED:
|
|
|
ESP_LOGD(TAG, "connected");
|
|
|
break;
|
|
@@ -126,8 +149,8 @@ esp_err_t http::Client::handleHttpEvent(esp_http_client_event_t *event) {
|
|
|
case HTTP_EVENT_ON_DATA:
|
|
|
ESP_LOGD(TAG, "data received");
|
|
|
if (esp_http_client_is_chunked_response(client->handle)) {
|
|
|
- ESP_LOGE(TAG, "received chunked data");
|
|
|
- ABORT("not implemented");
|
|
|
+ ESP_LOGE(TAG, "receiving chunked data not implemented");
|
|
|
+ throw kbf::exception::KBFError("HTTP client chunked data not implemented");
|
|
|
}
|
|
|
client->buffer.append((char *) event->data, event->data_len);
|
|
|
break;
|