Merge pull request #11018 from Dentomologist/add_updater_error_messages

Add updater error messages
This commit is contained in:
Admiral H. Curtiss 2022-11-15 01:08:55 +01:00 committed by GitHub
commit b6503d7585
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 37 deletions

View File

@ -635,15 +635,19 @@ bool DeleteDirRecursively(const std::string& directory)
return success; return success;
} }
// Create directory and copy contents (does not overwrite existing files) // Create directory and copy contents (optionally overwrites existing files)
void CopyDir(const std::string& source_path, const std::string& dest_path, bool destructive) bool CopyDir(const std::string& source_path, const std::string& dest_path, const bool destructive)
{ {
if (source_path == dest_path) if (source_path == dest_path)
return; return true;
if (!Exists(source_path)) if (!Exists(source_path))
return; return false;
// Shouldn't be used to short circuit operations after an earlier failure
bool everything_copied = true;
if (!Exists(dest_path)) if (!Exists(dest_path))
File::CreateFullPath(dest_path); everything_copied = File::CreateFullPath(dest_path) && everything_copied;
#ifdef _WIN32 #ifdef _WIN32
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
@ -652,7 +656,7 @@ void CopyDir(const std::string& source_path, const std::string& dest_path, bool
if (hFind == INVALID_HANDLE_VALUE) if (hFind == INVALID_HANDLE_VALUE)
{ {
FindClose(hFind); FindClose(hFind);
return; return false;
} }
do do
@ -661,7 +665,7 @@ void CopyDir(const std::string& source_path, const std::string& dest_path, bool
#else #else
DIR* dirp = opendir(source_path.c_str()); DIR* dirp = opendir(source_path.c_str());
if (!dirp) if (!dirp)
return; return false;
while (dirent* result = readdir(dirp)) while (dirent* result = readdir(dirp))
{ {
@ -671,21 +675,21 @@ void CopyDir(const std::string& source_path, const std::string& dest_path, bool
if (virtualName == "." || virtualName == "..") if (virtualName == "." || virtualName == "..")
continue; continue;
std::string source = source_path + DIR_SEP + virtualName; const std::string source = source_path + DIR_SEP + virtualName;
std::string dest = dest_path + DIR_SEP + virtualName; const std::string dest = dest_path + DIR_SEP + virtualName;
if (IsDirectory(source)) if (IsDirectory(source))
{ {
if (!Exists(dest)) if (!Exists(dest))
File::CreateFullPath(dest + DIR_SEP); File::CreateFullPath(dest + DIR_SEP);
CopyDir(source, dest, destructive); everything_copied = CopyDir(source, dest, destructive) && everything_copied;
} }
else if (!destructive && !Exists(dest)) else if (!destructive && !Exists(dest))
{ {
Copy(source, dest); everything_copied = Copy(source, dest) && everything_copied;
} }
else if (destructive) else if (destructive)
{ {
Rename(source, dest); everything_copied = Rename(source, dest) && everything_copied;
} }
#ifdef _WIN32 #ifdef _WIN32
} while (FindNextFile(hFind, &ffd) != 0); } while (FindNextFile(hFind, &ffd) != 0);
@ -694,6 +698,7 @@ void CopyDir(const std::string& source_path, const std::string& dest_path, bool
} }
closedir(dirp); closedir(dirp);
#endif #endif
return everything_copied;
} }
// Returns the current directory // Returns the current directory

View File

@ -193,7 +193,7 @@ bool DeleteDirRecursively(const std::string& directory);
std::string GetCurrentDir(); std::string GetCurrentDir();
// Create directory and copy contents (optionally overwrites existing files) // Create directory and copy contents (optionally overwrites existing files)
void CopyDir(const std::string& source_path, const std::string& dest_path, bool CopyDir(const std::string& source_path, const std::string& dest_path,
bool destructive = false); bool destructive = false);
// Set the current directory to given directory // Set the current directory to given directory

View File

@ -558,12 +558,7 @@ void MenuBar::InstallUpdateManually()
auto* const updater = new Updater(this->parentWidget(), manual_track, auto* const updater = new Updater(this->parentWidget(), manual_track,
Config::Get(Config::MAIN_AUTOUPDATE_HASH_OVERRIDE)); Config::Get(Config::MAIN_AUTOUPDATE_HASH_OVERRIDE));
if (!updater->CheckForUpdate()) updater->CheckForUpdate();
{
ModalMessageBox::information(
this, tr("Update"),
tr("You are running the latest version available on this update track."));
}
} }
void MenuBar::AddHelpMenu() void MenuBar::AddHelpMenu()

View File

@ -29,21 +29,19 @@ Updater::Updater(QWidget* parent, std::string update_track, std::string hash_ove
void Updater::run() void Updater::run()
{ {
AutoUpdateChecker::CheckForUpdate(m_update_track, m_hash_override); AutoUpdateChecker::CheckForUpdate(m_update_track, m_hash_override,
AutoUpdateChecker::CheckType::Automatic);
} }
bool Updater::CheckForUpdate() void Updater::CheckForUpdate()
{ {
m_update_available = false; AutoUpdateChecker::CheckForUpdate(m_update_track, m_hash_override,
AutoUpdateChecker::CheckForUpdate(m_update_track, m_hash_override); AutoUpdateChecker::CheckType::Manual);
return m_update_available;
} }
void Updater::OnUpdateAvailable(const NewVersionInformation& info) void Updater::OnUpdateAvailable(const NewVersionInformation& info)
{ {
bool later = false; bool later = false;
m_update_available = true;
std::optional<int> choice = RunOnObject(m_parent, [&] { std::optional<int> choice = RunOnObject(m_parent, [&] {
QDialog* dialog = new QDialog(m_parent); QDialog* dialog = new QDialog(m_parent);

View File

@ -21,11 +21,10 @@ public:
void run() override; void run() override;
void OnUpdateAvailable(const NewVersionInformation& info) override; void OnUpdateAvailable(const NewVersionInformation& info) override;
bool CheckForUpdate(); void CheckForUpdate();
private: private:
QWidget* m_parent; QWidget* m_parent;
std::string m_update_track; std::string m_update_track;
std::string m_hash_override; std::string m_hash_override;
bool m_update_available = false;
}; };

View File

@ -8,10 +8,12 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <picojson.h> #include <picojson.h>
#include "Common/CommonFuncs.h"
#include "Common/CommonPaths.h" #include "Common/CommonPaths.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/HttpRequest.h" #include "Common/HttpRequest.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/Version.h" #include "Common/Version.h"
@ -159,7 +161,7 @@ static std::string GetPlatformID()
} }
void AutoUpdateChecker::CheckForUpdate(std::string_view update_track, void AutoUpdateChecker::CheckForUpdate(std::string_view update_track,
std::string_view hash_override) std::string_view hash_override, const CheckType check_type)
{ {
// Don't bother checking if updates are not supported or not enabled. // Don't bother checking if updates are not supported or not enabled.
if (!SystemSupportsAutoUpdates() || update_track.empty()) if (!SystemSupportsAutoUpdates() || update_track.empty())
@ -173,11 +175,14 @@ void AutoUpdateChecker::CheckForUpdate(std::string_view update_track,
std::string url = fmt::format("https://dolphin-emu.org/update/check/v1/{}/{}/{}", update_track, std::string url = fmt::format("https://dolphin-emu.org/update/check/v1/{}/{}/{}", update_track,
version_hash, GetPlatformID()); version_hash, GetPlatformID());
const bool is_manual_check = check_type == CheckType::Manual;
Common::HttpRequest req{std::chrono::seconds{10}}; Common::HttpRequest req{std::chrono::seconds{10}};
auto resp = req.Get(url); auto resp = req.Get(url);
if (!resp) if (!resp)
{ {
ERROR_LOG_FMT(COMMON, "Auto-update request failed"); if (is_manual_check)
CriticalAlertFmtT("Unable to contact update server.");
return; return;
} }
const std::string contents(reinterpret_cast<char*>(resp->data()), resp->size()); const std::string contents(reinterpret_cast<char*>(resp->data()), resp->size());
@ -187,13 +192,15 @@ void AutoUpdateChecker::CheckForUpdate(std::string_view update_track,
const std::string err = picojson::parse(json, contents); const std::string err = picojson::parse(json, contents);
if (!err.empty()) if (!err.empty())
{ {
ERROR_LOG_FMT(COMMON, "Invalid JSON received from auto-update service: {}", err); CriticalAlertFmtT("Invalid JSON received from auto-update service : {0}", err);
return; return;
} }
picojson::object obj = json.get<picojson::object>(); picojson::object obj = json.get<picojson::object>();
if (obj["status"].get<std::string>() != "outdated") if (obj["status"].get<std::string>() != "outdated")
{ {
if (is_manual_check)
SuccessAlertFmtT("You are running the latest version available on this update track.");
INFO_LOG_FMT(COMMON, "Auto-update status: we are up to date."); INFO_LOG_FMT(COMMON, "Auto-update status: we are up to date.");
return; return;
} }
@ -212,7 +219,7 @@ void AutoUpdateChecker::CheckForUpdate(std::string_view update_track,
} }
void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info, void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info,
AutoUpdateChecker::RestartMode restart_mode) const AutoUpdateChecker::RestartMode restart_mode)
{ {
// Check to make sure we don't already have an update triggered // Check to make sure we don't already have an update triggered
if (s_update_triggered) if (s_update_triggered)
@ -241,8 +248,16 @@ void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInforma
#ifdef __APPLE__ #ifdef __APPLE__
// Copy the updater so it can update itself if needed. // Copy the updater so it can update itself if needed.
const std::string reloc_updater_path = UpdaterPath(true); const std::string reloc_updater_path = UpdaterPath(true);
File::CopyDir(UpdaterPath(), reloc_updater_path); if (!File::CopyDir(UpdaterPath(), reloc_updater_path))
chmod((reloc_updater_path + UPDATER_CONTENT_PATH).c_str(), 0700); {
CriticalAlertFmtT("Unable to create updater copy.");
return;
}
if (chmod((reloc_updater_path + UPDATER_CONTENT_PATH).c_str(), 0700) != 0)
{
CriticalAlertFmtT("Unable to set permissions on updater copy.");
return;
}
#endif #endif
// Run the updater! // Run the updater!
@ -261,12 +276,14 @@ void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInforma
} }
else else
{ {
ERROR_LOG_FMT(COMMON, "Could not start updater process: error={}", GetLastError()); const std::string error = GetLastErrorString();
CriticalAlertFmtT("Could not start updater process: {0}", error);
} }
#else #else
if (popen(command_line.c_str(), "r") == nullptr) if (popen(command_line.c_str(), "r") == nullptr)
{ {
ERROR_LOG_FMT(COMMON, "Could not start updater process: error={}", errno); const std::string error = LastStrerrorString();
CriticalAlertFmtT("Could not start updater process: {0}", error);
} }
#endif #endif

View File

@ -13,9 +13,15 @@
class AutoUpdateChecker class AutoUpdateChecker
{ {
public: public:
enum class CheckType
{
Automatic,
Manual,
};
// Initiates a check for updates in the background. Calls the OnUpdateAvailable callback if an // Initiates a check for updates in the background. Calls the OnUpdateAvailable callback if an
// update is available, does "nothing" otherwise. // update is available, does "nothing" otherwise.
void CheckForUpdate(std::string_view update_track, std::string_view hash_override); void CheckForUpdate(std::string_view update_track, std::string_view hash_override,
CheckType check_type);
static bool SystemSupportsAutoUpdates(); static bool SystemSupportsAutoUpdates();