Finalize implementation
This commit is contained in:
@@ -31,6 +31,7 @@ esp_http_client_handle_t g_sessionClient = nullptr;
|
||||
// the longest expected message including esp_err name (~32 chars), opcode (~10), heap
|
||||
// numbers, and HTTP status. Single-threaded sync flow makes static safe.
|
||||
char g_failureDetailBuf[160] = {0};
|
||||
char g_lastResponsePreview[160] = {0};
|
||||
|
||||
std::string previewBody(const char* body, const size_t maxLen = 120) {
|
||||
if (!body || !*body) {
|
||||
@@ -56,6 +57,12 @@ std::string previewBody(const char* body, const size_t maxLen = 120) {
|
||||
return preview;
|
||||
}
|
||||
|
||||
void rememberResponsePreview(const char* body) {
|
||||
const std::string preview = previewBody(body, sizeof(g_lastResponsePreview) - 1);
|
||||
strncpy(g_lastResponsePreview, preview.c_str(), sizeof(g_lastResponsePreview) - 1);
|
||||
g_lastResponsePreview[sizeof(g_lastResponsePreview) - 1] = '\0';
|
||||
}
|
||||
|
||||
// Reset the static diagnostic state at the start of each request and capture pre-flight
|
||||
// heap so failure reporting always reflects what was available when the request started.
|
||||
void beginRequest(const char* operation) {
|
||||
@@ -64,6 +71,7 @@ void beginRequest(const char* operation) {
|
||||
KOReaderSyncClient::lastHttpCode = 0;
|
||||
KOReaderSyncClient::lastHeapAtFailure = ESP.getFreeHeap();
|
||||
KOReaderSyncClient::lastContigHeapAtFailure = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT);
|
||||
g_lastResponsePreview[0] = '\0';
|
||||
}
|
||||
|
||||
// Skip a leading UTF-8 BOM (EF BB BF) and ASCII whitespace, returning a pointer
|
||||
@@ -475,7 +483,8 @@ KOReaderSyncClient::Error KOReaderSyncClient::getProgress(const std::string& doc
|
||||
LOG_DBG("KOSync", "GET %s -> %d (err: %s) [attempt %d body_len=%u]", url.c_str(), httpCode, esp_err_to_name(err),
|
||||
attempt, static_cast<unsigned>(bodyLen));
|
||||
if (err == ESP_OK && (httpCode < 200 || httpCode >= 300)) {
|
||||
LOG_ERR("KOSync", "GET failure body preview: %s", previewBody(activeBuf->data).c_str());
|
||||
rememberResponsePreview(activeBuf->data);
|
||||
LOG_ERR("KOSync", "GET failure body preview: %s", g_lastResponsePreview);
|
||||
}
|
||||
|
||||
// Retry exactly once for connect-level failures only.
|
||||
@@ -597,9 +606,10 @@ KOReaderSyncClient::Error KOReaderSyncClient::updateProgress(const KOReaderProgr
|
||||
LOG_DBG("KOSync", "PUT %s -> %d (err: %s) [attempt %d body_len=%u]", url.c_str(), httpCode, esp_err_to_name(err),
|
||||
attempt, static_cast<unsigned>(bodyLen));
|
||||
if (err == ESP_OK && (httpCode < 200 || httpCode >= 300)) {
|
||||
LOG_ERR("KOSync", "PUT failure body preview: %s", previewBody(activeBuf->data).c_str());
|
||||
LOG_ERR("KOSync", "PUT failure request summary: document=%s percentage=%.4f progress=%s", progress.document.c_str(),
|
||||
progress.percentage, progress.progress.c_str());
|
||||
rememberResponsePreview(activeBuf->data);
|
||||
LOG_ERR("KOSync", "PUT failure body preview: %s", g_lastResponsePreview);
|
||||
LOG_ERR("KOSync", "PUT failure request summary: document=%s percentage=%.4f progress=%s",
|
||||
progress.document.c_str(), progress.percentage, progress.progress.c_str());
|
||||
}
|
||||
|
||||
// Retry exactly once for connect-level failures only.
|
||||
@@ -670,6 +680,21 @@ const char* KOReaderSyncClient::lastFailureDetail() {
|
||||
}
|
||||
// Server case: got an HTTP status the client didn't recognize as success.
|
||||
if (lastHttpCode != 0) {
|
||||
if (lastHttpCode == 404 && lastOperation && strcmp(lastOperation, "update progress") == 0) {
|
||||
std::string lowerPreview = g_lastResponsePreview;
|
||||
std::transform(lowerPreview.begin(), lowerPreview.end(), lowerPreview.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
if (lowerPreview.find("book not found") != std::string::npos) {
|
||||
snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf),
|
||||
"%s: server does not know this book yet; server expects the same file to already exist there, usually "
|
||||
"downloaded via OPDS",
|
||||
lastOperation);
|
||||
return g_failureDetailBuf;
|
||||
}
|
||||
snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf),
|
||||
"%s: HTTP 404 (upload rejected; server may require book to be known)", lastOperation);
|
||||
return g_failureDetailBuf;
|
||||
}
|
||||
snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf), "%s: HTTP %d", lastOperation, lastHttpCode);
|
||||
return g_failureDetailBuf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user