[pim/trojita] src: Check that QFiles are open and dirs created
Espen Sandøy Hustad <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit a1f30f6ea9e93f506cfb3ee4a1f6bee73f8b8d8c by Espen Sandøy Hustad.
Committed on 03/08/2026 at 18:42.
Pushed by ehustad into branch 'master'.
Check that QFiles are open and dirs created
Add a new signal to PluginManager that signals if an error
occured during the creation of a plugin, and show a new warning
dialog box if this signal is emitted.
This allows throwing a std::runtime_exception when an error occurs on
Plugin::create, for example not being able to read a file or create a
directory.
Use this functionality to do proper error handling in the
abookaddressbook plugin, and fix the build warnings:
src/Plugins/AbookAddressbook/AbookAddressbook.cpp:194:9:
warning: ignoring return value of function declared with
'nodiscard' attribute [-Wunused-result]
src/Plugins/AbookAddressbook/AbookAddressbook.cpp:205:9:
warning: ignoring return value of function declared with
'nodiscard' attribute [-Wunused-result]
M +11 -0 src/Gui/Window.cpp
M +28 -5 src/Plugins/AbookAddressbook/AbookAddressbook.cpp
M +20 -3 src/Plugins/PluginManager.cpp
M +1 -0 src/Plugins/PluginManager.h
https://invent.kde.org/pim/trojita/-/commit/a1f30f6ea9e93f506cfb3ee4a1f6bee73f8b8d8c
diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp
index 9a028f8c2..f0d14438a 100644
--- a/src/Gui/Window.cpp
+++ b/src/Gui/Window.cpp
@@ -137,6 +137,17 @@ MainWindow::MainWindow(QSettings *settings): QMainWindow(), m_imapAccess(nullptr
"You might want to update your system or report a bug to your vendor."
"\n\n%1").arg(errorMessage));
});
+
+ connect(m_pluginManager, &Plugins::PluginManager::pluginCreateError, this, [this](const QString &name, const QString &description, const QString &errorMessage) {
+ Gui::Util::messageBoxWarning(this, tr("Plugin Error"),
+ //: The %1 placeholder is the name of the plugin.
+ //: The %2 placeholder is the human readable description of the plugin.
+ //: The %3 placeholder is the detailed error message, ready for human consumption.
+ tr("The plugin \"%1 (%2)\" failed to load, therefore some functionality might be lost. "
+ "\n\n%3").arg(name, description, errorMessage));
+
+ });
+
#ifdef TROJITA_HAVE_CRYPTO_MESSAGES
Plugins::PluginManager::MimePartReplacers replacers;
#ifdef TROJITA_HAVE_GPGMEPP
diff --git a/src/Plugins/AbookAddressbook/AbookAddressbook.cpp b/src/Plugins/AbookAddressbook/AbookAddressbook.cpp
index d3635fccf..1ae5251c0 100644
--- a/src/Plugins/AbookAddressbook/AbookAddressbook.cpp
+++ b/src/Plugins/AbookAddressbook/AbookAddressbook.cpp
@@ -194,7 +194,11 @@ void AbookAddressbook::createAbookDir()
return;
}
- dir.mkpath(dir.absolutePath());
+ if (!dir.mkpath(dir.absolutePath())) {
+ //: Translators: %1 is the filename of the abook dot directory
+ throw std::runtime_error(tr("Failed to create abook directory \"%1\": Do you have sufficient permissions?")
+ .arg(dir.absolutePath()).toStdString());
+ }
}
void AbookAddressbook::updateConfigFile() const
@@ -204,7 +208,13 @@ void AbookAddressbook::updateConfigFile() const
if (!file.exists()) {
abookrc << QStringLiteral("field photo = Photo") << QStringLiteral("set preserve_fields=all");
} else {
- file.open(QIODevice::ReadOnly|QIODevice::Text);
+ if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ //: Translators: %1 is the filename of the abook config file
+ //: %2 is the detailed error description from Qt, ready for human consumption
+ throw std::runtime_error(tr("Failed to open abook configfile \"%1\" for reading: %2")
+ .arg(file.fileName(), file.errorString()).toStdString());
+ }
+
abookrc = QString::fromLocal8Bit(file.readAll()).split(QStringLiteral("\n"));
bool havePhoto = false;
@@ -222,15 +232,28 @@ void AbookAddressbook::updateConfigFile() const
file.close();
}
- file.open(QIODevice::WriteOnly|QIODevice::Truncate);
+ if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
+ //: Translators: %1 is the filename of the abook config file
+ //: %2 is the detailed error description from Qt, ready for human consumption
+ throw std::runtime_error(tr("Failed to open abook configfile \"%1\" for writing: %2")
+ .arg(file.fileName(), file.errorString()).toStdString());
+ }
file.write(abookrc.join(QStringLiteral("\n")).toLocal8Bit());
}
void AbookAddressbook::createAbookDBFile() const
{
QFile abookFile(dbFileName());
- if (!abookFile.exists()) {
- abookFile.open(QIODevice::WriteOnly);
+ if (abookFile.exists()) {
+ return;
+ }
+
+ if (!abookFile.open(QIODevice::WriteOnly)) {
+ //: Translators: %1 is the filename of the abook database file
+ //: %2 is the detailed error description from Qt, ready for human consumption
+ throw std::runtime_error(tr("Failed to create abook database \"%1\": %2")
+ .arg(abookFile.fileName(), abookFile.errorString()).toStdString());
+
}
}
diff --git a/src/Plugins/PluginManager.cpp b/src/Plugins/PluginManager.cpp
index 38d2f9376..4cc8acbe0 100644
--- a/src/Plugins/PluginManager.cpp
+++ b/src/Plugins/PluginManager.cpp
@@ -227,7 +227,13 @@ void PluginManager::setAddressbookPlugin(const QString &name)
#ifdef PLUGIN_DEBUG
qDebug() << "Setting new address book plugin:" << (*plugin)->name();
#endif
- m_addressbook = (*plugin)->create(this, m_settings);
+ const QString description = (*plugin)->description();
+
+ try {
+ m_addressbook = (*plugin)->create(this, m_settings);
+ } catch (std::runtime_error &err) {
+ emit pluginCreateError(name, description, QString::fromStdString(err.what()));
+ }
}
emit pluginsChanged();
@@ -245,7 +251,13 @@ void PluginManager::setPasswordPlugin(const QString &name)
#ifdef PLUGIN_DEBUG
qDebug() << "Setting new password plugin:" << (*plugin)->name();
#endif
- m_password = (*plugin)->create(this, m_settings);
+ const QString description = (*plugin)->description();
+
+ try {
+ m_password = (*plugin)->create(this, m_settings);
+ } catch (std::runtime_error &err) {
+ emit pluginCreateError(name, description, QString::fromStdString(err.what()));
+ }
}
emit pluginsChanged();
@@ -263,7 +275,12 @@ void PluginManager::setSpellcheckerPlugin(const QString &name)
#ifdef PLUGIN_DEBUG
qDebug() << "Setting new spellchecker plugin:" << (*plugin)->name();
#endif
- m_spellchecker = (*plugin)->create(this, m_settings);
+ const QString description = (*plugin)->description();
+ try {
+ m_spellchecker = (*plugin)->create(this, m_settings);
+ } catch (std::runtime_error &err) {
+ emit pluginCreateError(name, description, QString::fromStdString(err.what()));
+ }
}
emit pluginsChanged();
diff --git a/src/Plugins/PluginManager.h b/src/Plugins/PluginManager.h
index c0a00a70d..705c92a4c 100644
--- a/src/Plugins/PluginManager.h
+++ b/src/Plugins/PluginManager.h
@@ -99,6 +99,7 @@ public:
signals:
void pluginsChanged();
void pluginError(const QString &errorMessage);
+ void pluginCreateError(const QString &name, const QString &description, const QString &errorMessage);
private slots:
void loadPlugins();