Commit 05768142 authored by David Redondo's avatar David Redondo 🏎

Add some rudimentary error handling to users kcm

Don't fail silently when an error occurs otherwise the kcm just looks broken.
Show at least an inline message so the user knows that something went wrong.
The comment was wrong. We can distinguish why an error occured. Furthermore,
even if it is a permission denied error we do not know if the user canceled
the action or if it failed for some other reason so also treat that as an
error.
BUG:425036
CCBUG:426932
FIXED-IN:5.20
CCMAIL:uhhadd@gmail.com
parent 4ed3a5d5
......@@ -37,10 +37,20 @@ SimpleKCM {
property bool overrideImage: false
property url oldImage
Connections {
target: user
function onApplyError(errorText) {
errorMessage.visible = true
errorMessage.text = errorText
}
}
Connections {
target: kcm
onApply: {
errorMessage.visible = false
usersDetailPage.user.realName = realNametextField.text
usersDetailPage.user.email = emailTextField.text
usersDetailPage.user.name = userNameField.text
......@@ -51,6 +61,7 @@ SimpleKCM {
}
onReset: {
errorMessage.visible = false
realNametextField.text = usersDetailPage.user.realName
emailTextField.text = usersDetailPage.user.email
userNameField.text = usersDetailPage.user.name
......@@ -90,7 +101,12 @@ SimpleKCM {
}
ColumnLayout {
Kirigami.InlineMessage {
id: errorMessage
visible: false
type: Kirigami.MessageType.Error
Layout.fillWidth: true
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
QQC2.RoundButton {
......
......@@ -27,6 +27,19 @@ qt5_add_dbus_interface(kcm_users_SRCS
login1_interface
)
ecm_qt_declare_logging_category(kcm_users_SRCS
HEADER kcmusers_debug.h
IDENTIFIER KCMUSERS
CATEGORY_NAME org.kde.kcm_users
EXPORT KCMUSERS
DESCRIPTION "System Settings - Users"
)
ecm_qt_install_logging_categories(
EXPORT KCMUSERS
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)
add_library(kcm_users MODULE ${kcm_users_SRCS})
target_link_libraries(kcm_users
......
/*
Copyright 2019 Nicolas Fella <nicolas.fella@gmx.de>
Copyright 2020 Carson Black <uhhadd@gmail.com>
Copyright 2020 David Redondo <kde@david-redondo.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -21,9 +22,11 @@
#include "user.h"
#include "user_interface.h"
#include "kcmusers_debug.h"
#include <unistd.h>
#include <sys/types.h>
#include <QtConcurrent>
#include <KLocalizedString>
User::User(QObject* parent) : QObject(parent) {}
......@@ -222,6 +225,19 @@ QDBusObjectPath User::path() const
void User::apply()
{
auto job = new UserApplyJob(m_dbusIface, mName, mEmail, mRealName, mFace.toString().replace("file://", ""), mAdministrator ? 1 : 0);
connect(job, &UserApplyJob::result, this, [this, job] {
switch (static_cast<UserApplyJob::Error>(job->error())) {
case UserApplyJob::Error::PermissionDenied:
Q_EMIT applyError(i18n("Could not get permission to save user %1", mName));
break;
case UserApplyJob::Error::Failed:
[[fallthrough]]
case UserApplyJob::Error::Unknown:
Q_EMIT applyError(i18n("There was an error while saving changes"));
break;
case UserApplyJob::Error::NoError: ; // Do nothing
}
});
job->start();
}
......@@ -255,14 +271,30 @@ void UserApplyJob::start()
for (auto const &x: set) {
auto resp = (m_dbusIface->*(x.second))(x.first);
resp.waitForFinished();
// We don't have a meaningful way to discern between errors and
// user cancellation; but user cancellation is more likely than errors
// so go with that.
if (resp.isError()) {
setError(resp.error());
qCWarning(KCMUSERS) << resp.error().name() << resp.error().message();
emitResult();
return;
}
}
m_dbusIface->SetAccountType(m_type).waitForFinished();
auto setAccount = m_dbusIface->SetAccountType(m_type);
setAccount.waitForFinished();
if (setAccount.isError()) {
setError(setAccount.error());
qCWarning(KCMUSERS) << setAccount.error().name() << setAccount.error().message();
}
emitResult();
}
void UserApplyJob::setError(const QDBusError& error)
{
setErrorText(error.message());
if (error.name() == QLatin1String("org.freedesktop.Accounts.Error.Failed")) {
KJob::setError(static_cast<int>(Error::Failed));
} else if (error.name() == QLatin1String("org.freedesktop.Accounts.Error.PermissionDenied")) {
KJob::setError(static_cast<int>(Error::PermissionDenied));
} else {
KJob::setError(static_cast<int>(Error::Unknown));
}
}
......@@ -28,6 +28,7 @@
#include <KJob>
class OrgFreedesktopAccountsUserInterface;
class QDBusError;
class UserApplyJob : public KJob {
Q_OBJECT
......@@ -36,7 +37,16 @@ public:
UserApplyJob(QPointer<OrgFreedesktopAccountsUserInterface> dbusIface, QString name, QString email, QString realname, QString icon, int type);
void start() override;
enum class Error {
NoError = 0,
PermissionDenied,
Failed,
Unknown
};
private:
void setError(const QDBusError &error);
QString m_name;
QString m_email;
QString m_realname;
......@@ -95,7 +105,7 @@ public:
public Q_SLOTS:
Q_SCRIPTABLE void apply();
signals:
Q_SIGNALS:
void dataChanged();
void uidChanged();
......@@ -105,6 +115,7 @@ signals:
void faceChanged();
void faceValidChanged();
void administratorChanged();
void applyError(const QString& errorMessage);
private:
int mUid = 0;
......
......@@ -21,13 +21,13 @@
#include "usermodel.h"
#include <QDebug>
#include <QDBusPendingReply>
#include <QDBusInterface>
#include <algorithm>
#include <KLocalizedString>
#include "accounts_interface.h"
#include "kcmusers_debug.h"
UserModel::UserModel(QObject* parent)
: QAbstractListModel(parent)
......@@ -60,7 +60,7 @@ UserModel::UserModel(QObject* parent)
reply.waitForFinished();
if (reply.isError()) {
qDebug() << reply.error().message();
qCWarning(KCMUSERS) << reply.error().message();
return;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment