From 03b3e1e5b72ca3b0c8281a356c74a93526f2ee1c Mon Sep 17 00:00:00 2001 From: jpirnay Date: Mon, 13 Apr 2026 11:32:19 +0200 Subject: [PATCH] Provide a clearer message for TLS 1.3 cases --- lib/KOReaderSync/KOReaderSyncClient.cpp | 13 +++++++++++-- src/activities/reader/KOReaderSyncActivity.cpp | 10 +++++++++- .../settings/KOReaderAuthActivity.cpp | 17 ++++++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/KOReaderSync/KOReaderSyncClient.cpp b/lib/KOReaderSync/KOReaderSyncClient.cpp index f40af195..b537d2e5 100644 --- a/lib/KOReaderSync/KOReaderSyncClient.cpp +++ b/lib/KOReaderSync/KOReaderSyncClient.cpp @@ -609,8 +609,17 @@ const char* KOReaderSyncClient::lastFailureDetail() { } // Network/TLS case: esp_http_client_perform() failed before getting a status code. if (lastHttpCode == 0 && lastEspError != 0) { - snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf), "%s: %s (heap %u/%u contig)", lastOperation, - esp_err_to_name(lastEspError), lastHeapAtFailure, lastContigHeapAtFailure); + // Detect TLS handshake failures on HTTPS URLs — likely caused by the server + // requiring TLS 1.3 which the ESP32 mbedTLS library does not support. + if (lastEspError == ESP_ERR_HTTP_CONNECT && KOREADER_STORE.getBaseUrl().rfind("https", 0) == 0) { + snprintf( + g_failureDetailBuf, sizeof(g_failureDetailBuf), + "%s: TLS handshake failed. Server may require TLS 1.3 (unsupported). Try a different server or use HTTP.", + lastOperation); + } else { + snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf), "%s: %s (heap %u/%u contig)", lastOperation, + esp_err_to_name(lastEspError), lastHeapAtFailure, lastContigHeapAtFailure); + } return g_failureDetailBuf; } // Server case: got an HTTP status the client didn't recognize as success. diff --git a/src/activities/reader/KOReaderSyncActivity.cpp b/src/activities/reader/KOReaderSyncActivity.cpp index 754c5d9a..522080c9 100644 --- a/src/activities/reader/KOReaderSyncActivity.cpp +++ b/src/activities/reader/KOReaderSyncActivity.cpp @@ -529,7 +529,15 @@ void KOReaderSyncActivity::render(RenderLock&&) { if (state == SYNC_FAILED) { renderer.drawCenteredText(UI_10_FONT_ID, 280, tr(STR_SYNC_FAILED_MSG), true, EpdFontFamily::BOLD); - renderer.drawCenteredText(UI_10_FONT_ID, 320, statusMessage.c_str()); + + // Word-wrap the detail message so long TLS/network diagnostics aren't clipped. + const int lineHeight = renderer.getLineHeight(UI_10_FONT_ID); + const auto lines = renderer.wrappedText(UI_10_FONT_ID, statusMessage.c_str(), contentRect.width - 20, 4); + int y = 320; + for (const auto& line : lines) { + renderer.drawCenteredText(UI_10_FONT_ID, y, line.c_str()); + y += lineHeight; + } const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", ""); GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); diff --git a/src/activities/settings/KOReaderAuthActivity.cpp b/src/activities/settings/KOReaderAuthActivity.cpp index e2733a91..6058b944 100644 --- a/src/activities/settings/KOReaderAuthActivity.cpp +++ b/src/activities/settings/KOReaderAuthActivity.cpp @@ -53,6 +53,11 @@ void KOReaderAuthActivity::performAuthentication() { } else { state = FAILED; errorMessage = KOReaderSyncClient::errorString(result); + const char* detail = KOReaderSyncClient::lastFailureDetail(); + if (detail && detail[0]) { + errorMessage += " — "; + errorMessage += detail; + } } } requestUpdate(); @@ -72,6 +77,11 @@ void KOReaderAuthActivity::performRegistration() { } else { state = FAILED; errorMessage = KOReaderSyncClient::errorString(result); + const char* detail = KOReaderSyncClient::lastFailureDetail(); + if (detail && detail[0]) { + errorMessage += " — "; + errorMessage += detail; + } } } requestUpdate(); @@ -120,7 +130,12 @@ void KOReaderAuthActivity::render(RenderLock&&) { } else if (state == FAILED) { const char* failedMsg = (mode == Mode::REGISTER) ? tr(STR_REGISTER_FAILED) : tr(STR_AUTH_FAILED); renderer.drawCenteredText(UI_10_FONT_ID, top, failedMsg, true, EpdFontFamily::BOLD); - renderer.drawCenteredText(UI_10_FONT_ID, top + height + 10, errorMessage.c_str()); + const auto lines = renderer.wrappedText(UI_10_FONT_ID, errorMessage.c_str(), contentRect.width - 20, 4); + int y = top + height + 10; + for (const auto& line : lines) { + renderer.drawCenteredText(UI_10_FONT_ID, y, line.c_str()); + y += height; + } } const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");