From ad337f97fe625e8a63c567310568599a8e6c7dc0 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 18 Jan 2023 21:33:10 +0100 Subject: [PATCH] Improve error messages when a download fails --- source/UpdateStateDownloadFiles.cpp | 14 ++++++++++++-- source/UpdateStateRender.cpp | 17 +++++++++++++++++ source/UpdaterState.h | 8 +++++++- source/UpdaterStateCheckVersions.cpp | 9 +++++++-- source/utils/DownloadUtils.cpp | 22 ++++++++++++++-------- source/utils/DownloadUtils.h | 6 ++++-- source/utils/UpdateUtils.cpp | 4 +++- 7 files changed, 64 insertions(+), 16 deletions(-) diff --git a/source/UpdateStateDownloadFiles.cpp b/source/UpdateStateDownloadFiles.cpp index f5aa882..1ea1208 100644 --- a/source/UpdateStateDownloadFiles.cpp +++ b/source/UpdateStateDownloadFiles.cpp @@ -28,11 +28,16 @@ int DownloadFilesThreadEntry(UpdaterState *updater) { int responseCode; updater->mProgress = 0.0f; DEBUG_FUNCTION_LINE("Download %s", curURL.c_str()); - if (DownloadUtils::DownloadFileToBuffer(curURL.c_str(), downloadedZIP, responseCode, &updater->mProgress) < 0 || responseCode != 200) { + int errorCode; + std::string errorText; + if (DownloadUtils::DownloadFileToBuffer(curURL, downloadedZIP, responseCode, errorCode, errorText, &updater->mProgress) < 0 || responseCode != 200) { DEBUG_FUNCTION_LINE_ERR("Download failed"); { std::lock_guard lockInfo(updater->mDownloadInfosLock); - updater->mDownloadInfos->state = DownloadInfos::DOWNLOAD_FAILED; + updater->mDownloadInfos->state = DownloadInfos::DOWNLOAD_FAILED; + updater->mDownloadInfos->errorCode = errorCode; + updater->mDownloadInfos->errorText = errorText; + updater->mDownloadInfos->responseCode = responseCode; OSMemoryBarrier(); return 0; } @@ -138,6 +143,11 @@ ApplicationState::eSubState UpdaterState::UpdateProcessDownloadFiles(Input *inpu this->mState = STATE_UPDATE_PROCESS_DOWNLOAD_FILES_FINISHED; break; case DownloadInfos::DOWNLOAD_FAILED: + if (this->mDownloadInfos) { + this->mResponseCode = this->mDownloadInfos->responseCode; + this->mDownloadErrorCode = this->mDownloadInfos->errorCode; + this->mDownloadErrorText = this->mDownloadInfos->errorText; + } setError(ERROR_DOWNLOAD_FAILED); break; case DownloadInfos::DOWNLOAD_EXTRACT_FAILED: diff --git a/source/UpdateStateRender.cpp b/source/UpdateStateRender.cpp index 69c8b16..bd5b8d6 100644 --- a/source/UpdateStateRender.cpp +++ b/source/UpdateStateRender.cpp @@ -1,5 +1,6 @@ #include "UpdaterState.h" #include "common.h" +#include "utils/DownloadUtils.h" #include "utils/UpdateUtils.h" #include @@ -12,6 +13,22 @@ void UpdaterState::RenderError() { if (this->mErrorState == ERROR_FAILED_COPY_FILES) { DrawUtils::print(16, 160, "Your Aroma installation might has been corrupted. Please re-download Aroma"); DrawUtils::print(16, 180, "from " AROMA_DOWNLOAD_URL " and replace the files on the sd card."); + } else if (this->mErrorState == ERROR_FAILED_TO_DOWNLOAD_VERSIONS || this->mErrorState == ERROR_DOWNLOAD_FAILED) { + if (this->mResponseCode != -1) { + DrawUtils::printf(16, 160, false, "Response code was %d", mResponseCode); + } else { + DrawUtils::printf(16, 160, false, "libcurl error code %d", mDownloadErrorCode); + DrawUtils::printf(16, 180, false, "(%s)", mDownloadErrorText.c_str()); + if (mDownloadErrorCode == 60 && (mDownloadErrorText.find("BADCERT_FUTURE") != std::string::npos || mDownloadErrorText.find("BADCERT_EXPIRED") != std::string::npos)) { + time_t now = time(nullptr); + DrawUtils::printf(16, 220, false, "Make sure your console has the correct date"); + DrawUtils::printf(16, 240, false, "Date of the console: %s", ctime(&now)); + } else if (mDownloadErrorCode == 0x13371337) { + DrawUtils::printf(16, 220, false, "Make sure to load this updater as .wuhb, not .rpx"); + } else if (mDownloadErrorCode == 6) { + DrawUtils::printf(16, 220, false, "Please check the internet connection of your console."); + } + } } DrawUtils::setFontSize(18); diff --git a/source/UpdaterState.h b/source/UpdaterState.h index ce988df..ceac0a3 100644 --- a/source/UpdaterState.h +++ b/source/UpdaterState.h @@ -26,7 +26,6 @@ #include #include - class DownloadInfos { public: explicit DownloadInfos(uint32_t totalFiles) : totalFiles(totalFiles) { @@ -51,6 +50,9 @@ public: std::optional curFile; eProcessStep processStep = STEP_DOWNLOAD; eDownloadFileState state = DOWNLOAD_RUNNING; + int errorCode = {}; + int responseCode = {}; + std::string errorText = {}; }; class UpdaterState : public ApplicationState { @@ -127,10 +129,14 @@ public: std::mutex mVersionBufferLock; std::string mVersionBuffer; + int mResponseCode; eErrorState mErrorState; VersionCheck::VersionInfo mVersionInfo; + int mDownloadErrorCode; + std::string mDownloadErrorText; + bool mOnlyRequired = false; int32_t mTotalPackageCount = 0; diff --git a/source/UpdaterStateCheckVersions.cpp b/source/UpdaterStateCheckVersions.cpp index 49fb1b1..ab069e0 100644 --- a/source/UpdaterStateCheckVersions.cpp +++ b/source/UpdaterStateCheckVersions.cpp @@ -9,9 +9,14 @@ int DownloadVersionInfoThreadEntry(UpdaterState *updater) { std::lock_guard lock(updater->mVersionBufferLock); - int responseCode; updater->mProgress = 0.0f; - if (DownloadUtils::DownloadFileToBuffer(UPDATE_SERVER_URL "/api/check_versions", updater->mVersionBuffer, responseCode, &updater->mProgress) < 0 || responseCode != 200) { + if (DownloadUtils::DownloadFileToBuffer(UPDATE_SERVER_URL "/api/check_versions", + updater->mVersionBuffer, + updater->mResponseCode, + updater->mDownloadErrorCode, + updater->mDownloadErrorText, + &updater->mProgress) < 0 || + updater->mResponseCode != 200) { DEBUG_FUNCTION_LINE_ERR("Error while downloading"); updater->mDownloadInfoResult = UpdaterState::DOWNLOAD_FAILED; } else { diff --git a/source/utils/DownloadUtils.cpp b/source/utils/DownloadUtils.cpp index 2011c94..f5da18b 100644 --- a/source/utils/DownloadUtils.cpp +++ b/source/utils/DownloadUtils.cpp @@ -90,7 +90,7 @@ void DownloadUtils::Deinit() { libInitDone = false; } -int DownloadUtils::DownloadFileToBuffer(const char *url, std::string &outBuffer, int &responseCodeOut, float *progress) { +int DownloadUtils::DownloadFileToBuffer(const std::string &url, std::string &outBuffer, int &responseCodeOut, int &errorOut, std::string &errorTextOut, float *progress) { if (!libInitDone) { return -1; } @@ -102,7 +102,6 @@ int DownloadUtils::DownloadFileToBuffer(const char *url, std::string &outBuffer, return -1; } - if (cacert_pem != nullptr) { struct curl_blob blob {}; blob.data = (void *) cacert_pem; @@ -112,6 +111,8 @@ int DownloadUtils::DownloadFileToBuffer(const char *url, std::string &outBuffer, // Use the certificate bundle in the data curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob); } else { + errorOut = 0x13371337; + errorTextOut = "cacert.pem is not loaded"; DEBUG_FUNCTION_LINE_ERR("Warning, missing certificate."); return -4; } @@ -123,7 +124,7 @@ int DownloadUtils::DownloadFileToBuffer(const char *url, std::string &outBuffer, curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // Set the download URL - curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); if (progress != nullptr) { /* pass struct to callback */ @@ -135,15 +136,20 @@ int DownloadUtils::DownloadFileToBuffer(const char *url, std::string &outBuffer, curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &outBuffer); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback); - if (curl_easy_perform(curl) != CURLE_OK) { + char error[CURL_ERROR_SIZE]; /* needs to be at least this big */ + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); + + errorTextOut = {}; + errorOut = 0; + + responseCodeOut = -1; + if ((errorOut = curl_easy_perform(curl)) != CURLE_OK) { + errorTextOut = error; curl_easy_cleanup(curl); curl_global_cleanup(); return -1; } - - int32_t response_code; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - responseCodeOut = response_code; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCodeOut); curl_easy_cleanup(curl); diff --git a/source/utils/DownloadUtils.h b/source/utils/DownloadUtils.h index 4b31f0b..ca13afb 100644 --- a/source/utils/DownloadUtils.h +++ b/source/utils/DownloadUtils.h @@ -5,10 +5,12 @@ class DownloadUtils { public: static bool Init(); static void Deinit(); - static int DownloadFileToBuffer(const char *url, std::string &outBuffer, int &responseCodeOut, float *progress); + + static int DownloadFileToBuffer(const std::string &url, std::string &outBuffer, int &responseCodeOut, int &errorOut, std::string &errorTextOut, float *progress); + + static uint32_t cacert_pem_size; private: static bool libInitDone; static uint8_t *cacert_pem; - static uint32_t cacert_pem_size; }; \ No newline at end of file diff --git a/source/utils/UpdateUtils.cpp b/source/utils/UpdateUtils.cpp index 25ece18..c672930 100644 --- a/source/utils/UpdateUtils.cpp +++ b/source/utils/UpdateUtils.cpp @@ -46,7 +46,9 @@ void UpdateUtils::CheckFilesOfVersionInfo(VersionCheck::VersionInfo &versionInfo std::string url = string_format("%s/api/check_versions?hash=%s", serverURL.c_str(), hashOfFileOnSDCard->c_str()); DEBUG_FUNCTION_LINE("Check version of file with hash %s", hashOfFileOnSDCard->c_str()); - if (DownloadUtils::DownloadFileToBuffer(url.c_str(), outBuffer2, responseCode, nullptr) < 0 && + int errorOut; + std::string errorTextOut; + if (DownloadUtils::DownloadFileToBuffer(url.c_str(), outBuffer2, responseCode, errorOut, errorTextOut, nullptr) < 0 && responseCode == 200) { DEBUG_FUNCTION_LINE("Failed to get information for the file"); file.setStatus(VersionCheck::FileStatus::Error);