aboutsummaryrefslogtreecommitdiff
path: root/src/omemo
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2023-01-22 18:06:09 +0100
committerLinus Jahn <lnj@kaidan.im>2023-01-22 18:10:44 +0100
commit46f3831fd238b4c1fb10d44e4531d9e59d574c97 (patch)
treef21c85c98502ef3821d52ee4964060a2c49885d2 /src/omemo
parentdf37c35aa443e6ca7e3baad5f1bbeb379063df55 (diff)
downloadqxmpp-46f3831fd238b4c1fb10d44e4531d9e59d574c97.tar.gz
Use QXmppError in all IQ results instead of StanzaError
This allows us to report different error types with more information and makes it possible to distinguish stanza errors and errors generated locally. Part of #501.
Diffstat (limited to 'src/omemo')
-rw-r--r--src/omemo/QXmppOmemoManager.cpp6
-rw-r--r--src/omemo/QXmppOmemoManager.h2
-rw-r--r--src/omemo/QXmppOmemoManager_p.cpp78
-rw-r--r--src/omemo/QXmppOmemoManager_p.h2
4 files changed, 50 insertions, 38 deletions
diff --git a/src/omemo/QXmppOmemoManager.cpp b/src/omemo/QXmppOmemoManager.cpp
index a90e3f53..af12879c 100644
--- a/src/omemo/QXmppOmemoManager.cpp
+++ b/src/omemo/QXmppOmemoManager.cpp
@@ -22,7 +22,6 @@ using namespace QXmpp;
using namespace QXmpp::Private;
using namespace QXmpp::Omemo::Private;
-using Error = QXmppStanza::Error;
using Manager = QXmppOmemoManager;
using ManagerPrivate = QXmppOmemoManagerPrivate;
@@ -629,8 +628,7 @@ QXmppTask<QVector<Manager::DevicesResult>> Manager::subscribeToDeviceLists(const
state->jidsCount = jids.size();
for (const auto &jid : jids) {
- auto future = d->subscribeToDeviceList(jid);
- future.then(this, [state, jid](QXmppPubSubManager::Result result) mutable {
+ d->subscribeToDeviceList(jid).then(this, [state, jid](QXmppPubSubManager::Result result) mutable {
Manager::DevicesResult devicesResult;
devicesResult.jid = jid;
devicesResult.result = result;
@@ -759,7 +757,7 @@ QXmppTask<QXmppPubSubManager::Result> Manager::removeContactDevices(const QStrin
auto future = d->unsubscribeFromDeviceList(jid);
future.then(this, [=](QXmppPubSubManager::Result result) mutable {
- if (std::holds_alternative<QXmppStanza::Error>(result)) {
+ if (std::holds_alternative<QXmppError>(result)) {
warning("Contact '" % jid % "' could not be removed because the device list subscription could not be removed");
interface.finish(std::move(result));
} else {
diff --git a/src/omemo/QXmppOmemoManager.h b/src/omemo/QXmppOmemoManager.h
index d7b34a9c..04f355b6 100644
--- a/src/omemo/QXmppOmemoManager.h
+++ b/src/omemo/QXmppOmemoManager.h
@@ -70,7 +70,7 @@ class QXMPPOMEMO_EXPORT QXmppOmemoManager : public QXmppClientExtension, public
Q_OBJECT
public:
- using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
+ using Result = std::variant<QXmpp::Success, QXmppError>;
struct DevicesResult
{
diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp
index b5ccac90..dea38c13 100644
--- a/src/omemo/QXmppOmemoManager_p.cpp
+++ b/src/omemo/QXmppOmemoManager_p.cpp
@@ -178,6 +178,14 @@ static QString errorToString(const QXmppStanza::Error &err)
QString::number(err.condition()) % u")";
}
+static QString errorToString(const QXmppError &err)
+{
+ if (auto sErr = err.value<QXmppStanza::Error>()) {
+ return errorToString(*sErr);
+ }
+ return err.description;
+}
+
static void replaceChildElements(QDomElement &oldElement, const QDomElement &newElement)
{
// remove old child elements
@@ -623,18 +631,24 @@ QXmppTask<bool> ManagerPrivate::setUpDeviceId()
// respond with an error (at least ejabberd 22.05 responds with an empty node instead).
// 2. There is an empty PubSub node for device bundles: XEP-0030 states that a server must
// respond with a node without included items.
- if (auto error = std::get_if<Error>(&result); error && !(error->type() == Error::Cancel && error->condition() == Error::ItemNotFound)) {
- warning("Existing / Published device IDs could not be retrieved: " % errorToString(*error));
- return false;
- } else {
- // The first generated device ID can be used if no device bundle node exists.
- // Otherwise, duplicates must be avoided.
- auto deviceId = error ? generateDeviceId() : generateDeviceId(std::get<QVector<QString>>(result));
- if (deviceId) {
- ownDevice.id = *deviceId;
+ auto error = std::get_if<QXmppError>(&result);
+ if (auto stanzaErr = error->value<QXmppStanza::Error>()) {
+ // allow Cancel|ItemNotFound here
+ if (!(stanzaErr->type() == Error::Cancel && stanzaErr->condition() == Error::ItemNotFound)) {
+ warning("Existing / Published device IDs could not be retrieved: " % errorToString(*error));
+ return false;
}
- return deviceId.has_value();
+ } else {
+ return false;
+ }
+
+ // The first generated device ID can be used if no device bundle node exists.
+ // Otherwise, duplicates must be avoided.
+ auto deviceId = error ? generateDeviceId() : generateDeviceId(std::get<QVector<QString>>(result));
+ if (deviceId) {
+ ownDevice.id = *deviceId;
}
+ return deviceId.has_value();
});
}
@@ -1892,7 +1906,7 @@ QXmppTask<bool> ManagerPrivate::publishOmemoData()
auto future = pubSubManager->requestOwnPepFeatures();
future.then(q, [=](QXmppPubSubManager::FeaturesResult result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Features of PEP service '" % ownBareJid() % "' could not be retrieved: " % errorToString(*error));
warning("Device bundle and device list could not be published");
interface.finish(false);
@@ -1910,7 +1924,7 @@ QXmppTask<bool> ManagerPrivate::publishOmemoData()
if (pepServiceFeatures.contains(ns_pubsub_publish)) {
auto future = pubSubManager->requestOwnPepNodes();
future.then(q, [=](QXmppPubSubManager::NodesResult result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Nodes of JID '" % ownBareJid() % "' could not be fetched to check if nodes '" %
QString(ns_omemo_2_bundles) % "' and '" % QString(ns_omemo_2_devices) %
"' exist: " % errorToString(*error));
@@ -2321,7 +2335,7 @@ QXmppTask<std::optional<QXmppOmemoDeviceBundle>> ManagerPrivate::requestDeviceBu
auto future = pubSubManager->requestItem<QXmppOmemoDeviceBundleItem>(deviceOwnerJid, ns_omemo_2_bundles, QString::number(deviceId));
future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceBundleItem> result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Device bundle for JID '" % deviceOwnerJid % "' and device ID '" %
QString::number(deviceId) % "' could not be retrieved: " % errorToString(*error));
interface.finish(std::nullopt);
@@ -2626,7 +2640,7 @@ void ManagerPrivate::updateOwnDevicesLocally(bool isDeviceListNodeExistent, Func
if (isDeviceListNodeExistent && otherOwnDevices().isEmpty()) {
auto future = pubSubManager->requestOwnPepItem<QXmppOmemoDeviceListItem>(ns_omemo_2_devices, QXmppPubSubManager::Current);
future.then(q, [=](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Device list for JID '" % ownBareJid() %
"' could not be retrieved and thus not updated: " %
errorToString(*error));
@@ -2845,14 +2859,14 @@ void ManagerPrivate::handleIrregularDeviceListChanges(const QString &deviceOwner
// the node's items are removed.
auto future = pubSubManager->deleteOwnPepNode(ns_omemo_2_devices);
future.then(q, [=](QXmppPubSubManager::Result result) {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Node '" % QString(ns_omemo_2_devices) % "' of JID '" % deviceOwnerJid %
"' could not be deleted in order to recover from an inconsistent node: " %
errorToString(*error));
} else {
auto future = pubSubManager->requestOwnPepFeatures();
future.then(q, [=](QXmppPubSubManager::FeaturesResult result) {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Features of PEP service '" % deviceOwnerJid %
"' could not be retrieved: " % errorToString(*error));
warning("Device list could not be published");
@@ -2985,18 +2999,18 @@ void ManagerPrivate::deleteNode(const QString &node, Function continuation)
{
auto future = pubSubManager->deleteOwnPepNode(node);
future.then(q, [=, continuation = std::move(continuation)](QXmppPubSubManager::Result result) mutable {
- const auto error = std::get_if<Error>(&result);
- if (error) {
- const auto errorType = error->type();
- const auto errorCondition = error->condition();
-
- // Skip the error handling if the node is already deleted.
- if (!(errorType == Error::Cancel && errorCondition == Error::ItemNotFound)) {
- warning("Node '" % node % "' of JID '" % ownBareJid() % "' could not be deleted: " %
- errorToString(*error));
- continuation(false);
+ if (auto error = std::get_if<QXmppError>(&result)) {
+ if (auto err = error->value<QXmppStanza::Error>()) {
+ // Skip the error handling if the node is already deleted.
+ if (!(err->type() == Error::Cancel && err->condition() == Error::ItemNotFound)) {
+ warning("Node '" % node % "' of JID '" % ownBareJid() % "' could not be deleted: " %
+ errorToString(*error));
+ continuation(false);
+ } else {
+ continuation(true);
+ }
} else {
- continuation(true);
+ continuation(false);
}
} else {
continuation(true);
@@ -3048,7 +3062,7 @@ template<typename T, typename Function>
void QXmppOmemoManagerPrivate::runPubSubQueryWithContinuation(QXmppTask<T> future, const QString &errorMessage, Function continuation)
{
future.then(q, [this, errorMessage, continuation = std::move(continuation)](auto result) mutable {
- if (auto error = std::get_if<Error>(&result)) {
+ if (auto error = std::get_if<QXmppError>(&result)) {
warning(errorMessage % u": " % errorToString(*error));
continuation(false);
} else {
@@ -3093,7 +3107,7 @@ QXmppTask<QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem>> ManagerPriva
{
auto future = pubSubManager->requestItem<QXmppOmemoDeviceListItem>(jid, ns_omemo_2_devices, QXmppPubSubManager::Current);
future.then(q, [this, jid](QXmppPubSubManager::ItemResult<QXmppOmemoDeviceListItem> result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Device list for JID '" % jid % "' could not be retrieved: " % errorToString(*error));
} else {
const auto &item = std::get<QXmppOmemoDeviceListItem>(result);
@@ -3133,9 +3147,9 @@ QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::subscribeToDeviceList(cons
auto future = pubSubManager->subscribeToNode(jid, ns_omemo_2_devices, ownFullJid());
future.then(q, [=](QXmppPubSubManager::Result result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Device list for JID '" % jid % "' could not be subscribed: " % errorToString(*error));
- interface.finish(*error);
+ interface.finish(std::move(*error));
} else {
jidsOfManuallySubscribedDevices.append(jid);
@@ -3206,7 +3220,7 @@ QXmppTask<QXmppPubSubManager::Result> ManagerPrivate::unsubscribeFromDeviceList(
auto future = pubSubManager->unsubscribeFromNode(jid, ns_omemo_2_devices, ownFullJid());
future.then(q, [=](QXmppPubSubManager::Result result) mutable {
- if (const auto error = std::get_if<Error>(&result)) {
+ if (const auto error = std::get_if<QXmppError>(&result)) {
warning("Device list for JID '" % jid % "' could not be unsubscribed: " % errorToString(*error));
} else {
jidsOfManuallySubscribedDevices.removeAll(jid);
diff --git a/src/omemo/QXmppOmemoManager_p.h b/src/omemo/QXmppOmemoManager_p.h
index bce22042..6875a571 100644
--- a/src/omemo/QXmppOmemoManager_p.h
+++ b/src/omemo/QXmppOmemoManager_p.h
@@ -125,7 +125,7 @@ using namespace QXmpp::Omemo::Private;
class QXmppOmemoManagerPrivate
{
public:
- using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
+ using Result = std::variant<QXmpp::Success, QXmppError>;
QXmppOmemoManager *q;