fix: don't emit until final retry

Also more descriptive error messages
This commit is contained in:
2 * r + 2 * t 2026-04-12 02:30:24 +10:00
parent 24367dfb3a
commit 1ad6f657ae
2 changed files with 26 additions and 20 deletions

View file

@ -20,7 +20,7 @@ void RootConfig::setupFileBackend(const QString& path) {
m_retryTimer->setSingleShot(true); m_retryTimer->setSingleShot(true);
m_retryTimer->setInterval(50); m_retryTimer->setInterval(50);
connect(m_retryTimer, &QTimer::timeout, this, &RootConfig::reloadFromFile); connect(m_retryTimer, &QTimer::timeout, this, &RootConfig::reload);
m_saveTimer->setSingleShot(true); m_saveTimer->setSingleShot(true);
m_saveTimer->setInterval(500); m_saveTimer->setInterval(500);
@ -29,8 +29,9 @@ void RootConfig::setupFileBackend(const QString& path) {
QFile file(m_filePath); QFile file(m_filePath);
if (!file.open(QIODevice::WriteOnly)) { if (!file.open(QIODevice::WriteOnly)) {
qCWarning(lcConfig, "Failed to write %s", qUtf8Printable(m_filePath)); auto err = QStringLiteral("Failed to write %1: %2").arg(m_filePath, file.errorString());
emit saveFailed(QStringLiteral("Failed to open file for writing")); qCWarning(lcConfig, "%s", qUtf8Printable(err));
emit saveFailed(err);
return; return;
} }
@ -50,7 +51,7 @@ void RootConfig::setupFileBackend(const QString& path) {
qCDebug(lcConfig) << "Setting up file backend for" << metaObject()->className() << "at" << path; qCDebug(lcConfig) << "Setting up file backend for" << metaObject()->className() << "at" << path;
reloadFromFile(); reload();
if (QFile::exists(m_filePath)) if (QFile::exists(m_filePath))
m_watcher->addPath(m_filePath); m_watcher->addPath(m_filePath);
@ -64,12 +65,13 @@ void RootConfig::saveToFile() {
m_cooldownTimer->start(); m_cooldownTimer->start();
} }
bool RootConfig::reloadFromFile() { std::optional<QString> RootConfig::reloadFromFile() {
QFile file(m_filePath); QFile file(m_filePath);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qCDebug(lcConfig, "Failed to open %s", qUtf8Printable(m_filePath)); auto err = QStringLiteral("Failed to open %1: %2").arg(m_filePath, file.errorString());
return false; qCDebug(lcConfig, "%s", qUtf8Printable(err));
return err;
} }
QJsonParseError error{}; QJsonParseError error{};
@ -81,12 +83,12 @@ bool RootConfig::reloadFromFile() {
qCDebug(lcConfig, "Failed to parse %s: %s - retrying (%d/3)", qUtf8Printable(m_filePath), qCDebug(lcConfig, "Failed to parse %s: %s - retrying (%d/3)", qUtf8Printable(m_filePath),
qUtf8Printable(error.errorString()), m_parseRetries); qUtf8Printable(error.errorString()), m_parseRetries);
m_retryTimer->start(); m_retryTimer->start();
} else { return std::nullopt; // pending retry — no signal
qCWarning(
lcConfig, "Failed to parse %s: %s", qUtf8Printable(m_filePath), qUtf8Printable(error.errorString()));
m_parseRetries = 0;
} }
return false;
qCWarning(lcConfig, "Failed to parse %s: %s", qUtf8Printable(m_filePath), qUtf8Printable(error.errorString()));
m_parseRetries = 0;
return error.errorString();
} }
m_parseRetries = 0; m_parseRetries = 0;
@ -96,7 +98,7 @@ bool RootConfig::reloadFromFile() {
clearLoadedKeys(); clearLoadedKeys();
loadFromJson(doc.object()); loadFromJson(doc.object());
return true; return QString(); // success
} }
void RootConfig::onFileChanged() { void RootConfig::onFileChanged() {
@ -108,10 +110,7 @@ void RootConfig::onFileChanged() {
if (m_retryTimer) if (m_retryTimer)
m_retryTimer->stop(); m_retryTimer->stop();
if (reloadFromFile()) reload();
emit loaded();
else
emit loadFailed(QStringLiteral("Failed to load config file"));
} }
} }
@ -120,8 +119,13 @@ void RootConfig::save() {
} }
void RootConfig::reload() { void RootConfig::reload() {
if (reloadFromFile()) auto result = reloadFromFile();
if (result.has_value()) {
if (result->isEmpty())
emit loaded(); emit loaded();
else
emit loadFailed(*result);
}
} }
} // namespace caelestia::config } // namespace caelestia::config

View file

@ -2,6 +2,7 @@
#include "configobject.hpp" #include "configobject.hpp"
#include <optional>
#include <qfilesystemwatcher.h> #include <qfilesystemwatcher.h>
#include <qtimer.h> #include <qtimer.h>
@ -17,7 +18,8 @@ public:
void setupFileBackend(const QString& path); void setupFileBackend(const QString& path);
void saveToFile(); void saveToFile();
bool reloadFromFile(); // Returns nullopt if retrying, empty string on success, error message on failure.
[[nodiscard]] std::optional<QString> reloadFromFile();
[[nodiscard]] bool recentlySaved() const { return m_recentlySaved; } [[nodiscard]] bool recentlySaved() const { return m_recentlySaved; }