aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/base/QXmppFutureUtils_p.h9
-rw-r--r--src/base/QXmppStream.cpp9
-rw-r--r--src/client/QXmppClient.h2
-rw-r--r--src/client/QXmppDiscoveryManager.h6
-rw-r--r--src/client/QXmppEntityTimeManager.h4
-rw-r--r--src/client/QXmppHttpUploadManager.cpp4
-rw-r--r--src/client/QXmppPep_p.h9
-rw-r--r--src/client/QXmppPubSubManager.cpp13
-rw-r--r--src/client/QXmppPubSubManager.h29
-rw-r--r--src/client/QXmppRosterManager.cpp7
-rw-r--r--src/client/QXmppRosterManager.h4
-rw-r--r--src/client/QXmppUploadRequestManager.cpp5
-rw-r--r--src/client/QXmppUploadRequestManager.h8
-rw-r--r--src/client/QXmppUserLocationManager.h5
-rw-r--r--src/client/QXmppUserTuneManager.h5
-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
19 files changed, 108 insertions, 99 deletions
diff --git a/src/base/QXmppFutureUtils_p.h b/src/base/QXmppFutureUtils_p.h
index 5e6b5ca8..95150008 100644
--- a/src/base/QXmppFutureUtils_p.h
+++ b/src/base/QXmppFutureUtils_p.h
@@ -158,14 +158,15 @@ auto parseIq(Input &&sendResult, Converter convert) -> decltype(convert({}))
IqType iq;
iq.parse(element);
if (iq.type() == QXmppIq::Error) {
- return iq.error();
+ if (auto err = iq.errorOptional()) {
+ return QXmppError { err->text(), std::move(*err) };
+ }
+ return QXmppError { QStringLiteral("Unknown error.") };
}
return convert(std::move(iq));
},
[](QXmppError error) -> Result {
- using Error = QXmppStanza::Error;
- return Error(Error::Wait, Error::UndefinedCondition,
- QStringLiteral("Couldn't send request: ") + error.description);
+ return error;
},
},
sendResult);
diff --git a/src/base/QXmppStream.cpp b/src/base/QXmppStream.cpp
index d1a5ccd2..7274e242 100644
--- a/src/base/QXmppStream.cpp
+++ b/src/base/QXmppStream.cpp
@@ -251,8 +251,8 @@ QXmppTask<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const
auto sendFuture = send(std::move(packet));
if (sendFuture.isFinished()) {
- if (std::holds_alternative<QXmppError>(sendFuture.result())) {
- // early exit (saves QFutureWatcher)
+ if (std::holds_alternative<QXmppError>(sendFuture.takeResult())) {
+ // early exit
return makeReadyTask<IqResult>(std::get<QXmppError>(sendFuture.result()));
}
} else {
@@ -266,10 +266,7 @@ QXmppTask<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const
});
}
- IqState state {
- {},
- to,
- };
+ IqState state { {}, to };
auto task = state.interface.task();
d->runningIqs.insert(id, std::move(state));
return task;
diff --git a/src/client/QXmppClient.h b/src/client/QXmppClient.h
index 5cef5fe3..ca33afb6 100644
--- a/src/client/QXmppClient.h
+++ b/src/client/QXmppClient.h
@@ -91,7 +91,7 @@ class QXMPP_EXPORT QXmppClient : public QXmppLoggable
public:
using IqResult = std::variant<QDomElement, QXmppError>;
- using EmptyResult = std::variant<QXmpp::Success, QXmppStanza::Error>;
+ using EmptyResult = std::variant<QXmpp::Success, QXmppError>;
/// An enumeration for type of error.
/// Error could come due a TCP socket or XML stream or due to various stanzas.
diff --git a/src/client/QXmppDiscoveryManager.h b/src/client/QXmppDiscoveryManager.h
index 56f6dfc4..10744a0d 100644
--- a/src/client/QXmppDiscoveryManager.h
+++ b/src/client/QXmppDiscoveryManager.h
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2010 Manjeet Dahiya <manjeetdahiya@gmail.com>
+// SPDX-FileCopyrightText: 2021 Linus Jahn <lnj@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -14,6 +15,7 @@ class QXmppTask;
class QXmppDataForm;
class QXmppDiscoveryIq;
class QXmppDiscoveryManagerPrivate;
+class QXmppError;
/// \brief The QXmppDiscoveryManager class makes it possible to discover information
/// about other entities as defined by \xep{0030}: Service Discovery.
@@ -33,8 +35,8 @@ public:
QString requestInfo(const QString &jid, const QString &node = QString());
QString requestItems(const QString &jid, const QString &node = QString());
- using InfoResult = std::variant<QXmppDiscoveryIq, QXmppStanza::Error>;
- using ItemsResult = std::variant<QList<QXmppDiscoveryIq::Item>, QXmppStanza::Error>;
+ using InfoResult = std::variant<QXmppDiscoveryIq, QXmppError>;
+ using ItemsResult = std::variant<QList<QXmppDiscoveryIq::Item>, QXmppError>;
QXmppTask<InfoResult> requestDiscoInfo(const QString &jid, const QString &node = {});
QXmppTask<ItemsResult> requestDiscoItems(const QString &jid, const QString &node = {});
diff --git a/src/client/QXmppEntityTimeManager.h b/src/client/QXmppEntityTimeManager.h
index 81c6fb45..3b090feb 100644
--- a/src/client/QXmppEntityTimeManager.h
+++ b/src/client/QXmppEntityTimeManager.h
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2010 Manjeet Dahiya <manjeetdahiya@gmail.com>
+// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -12,6 +13,7 @@
template<class T>
class QXmppTask;
class QXmppEntityTimeIq;
+class QXmppError;
///
/// \brief The QXmppEntityTimeManager class provided the functionality to get
@@ -26,7 +28,7 @@ class QXMPP_EXPORT QXmppEntityTimeManager : public QXmppClientExtension
public:
QString requestTime(const QString &jid);
- using EntityTimeResult = std::variant<QXmppEntityTimeIq, QXmppStanza::Error>;
+ using EntityTimeResult = std::variant<QXmppEntityTimeIq, QXmppError>;
QXmppTask<EntityTimeResult> requestEntityTime(const QString &jid);
/// \cond
diff --git a/src/client/QXmppHttpUploadManager.cpp b/src/client/QXmppHttpUploadManager.cpp
index 35eedf80..c5b3fe89 100644
--- a/src/client/QXmppHttpUploadManager.cpp
+++ b/src/client/QXmppHttpUploadManager.cpp
@@ -307,8 +307,8 @@ std::shared_ptr<QXmppHttpUpload> QXmppHttpUploadManager::uploadFile(std::unique_
return;
}
- if (std::holds_alternative<QXmppStanza::Error>(result)) {
- upload->d->reportError(std::get<QXmppStanza::Error>(std::move(result)));
+ if (std::holds_alternative<QXmppError>(result)) {
+ upload->d->reportError(std::get<QXmppError>(std::move(result)));
upload->d->reportFinished();
} else {
auto slot = std::get<QXmppHttpUploadSlotIq>(std::move(result));
diff --git a/src/client/QXmppPep_p.h b/src/client/QXmppPep_p.h
index aafc6520..ea7f0440 100644
--- a/src/client/QXmppPep_p.h
+++ b/src/client/QXmppPep_p.h
@@ -8,23 +8,22 @@
namespace QXmpp::Private::Pep {
template<typename T>
-using GetResult = std::variant<T, QXmppStanza::Error>;
-using PublishResult = std::variant<QString, QXmppStanza::Error>;
+using GetResult = std::variant<T, QXmppError>;
+using PublishResult = std::variant<QString, QXmppError>;
template<typename ItemT>
inline QXmppTask<GetResult<ItemT>> request(QXmppPubSubManager *pubSub, const QString &jid, const QString &nodeName, QObject *parent)
{
using PubSub = QXmppPubSubManager;
- using Error = QXmppStanza::Error;
auto process = [](PubSub::ItemsResult<ItemT> &&result) -> GetResult<ItemT> {
if (const auto itemsResult = std::get_if<PubSub::Items<ItemT>>(&result)) {
if (!itemsResult->items.isEmpty()) {
return itemsResult->items.takeFirst();
}
- return Error(Error::Cancel, Error::ItemNotFound, QStringLiteral("User has no published items."));
+ return QXmppError { QStringLiteral("User has no published items."), {} };
} else {
- return std::get<Error>(result);
+ return std::get<QXmppError>(std::move(result));
}
};
return chain<GetResult<ItemT>>(pubSub->requestItems<ItemT>(jid, nodeName), parent, process);
diff --git a/src/client/QXmppPubSubManager.cpp b/src/client/QXmppPubSubManager.cpp
index a10fc25b..18ad9d7a 100644
--- a/src/client/QXmppPubSubManager.cpp
+++ b/src/client/QXmppPubSubManager.cpp
@@ -596,12 +596,7 @@ QXmppTask<QXmppPubSubManager::OptionsResult> QXmppPubSubManager::requestSubscrib
return *options;
}
}
-
- // "real" stanza errors are already handled
- using Error = QXmppStanza::Error;
- return Error(Error::Cancel,
- Error::Condition::InternalServerError,
- QStringLiteral("Server returned invalid data form."));
+ return QXmppError { QStringLiteral("Server returned invalid data form."), {} };
});
}
@@ -655,8 +650,6 @@ QXmppTask<QXmppPubSubManager::Result> QXmppPubSubManager::setSubscribeOptions(co
///
QXmppTask<QXmppPubSubManager::NodeConfigResult> QXmppPubSubManager::requestNodeConfiguration(const QString &service, const QString &nodeName)
{
- using Error = QXmppStanza::Error;
-
PubSubIq request;
request.setType(QXmppIq::Get);
request.setTo(service);
@@ -669,9 +662,9 @@ QXmppTask<QXmppPubSubManager::NodeConfigResult> QXmppPubSubManager::requestNodeC
if (const auto config = QXmppPubSubNodeConfig::fromDataForm(*dataForm)) {
return *config;
}
- return Error(Error::Cancel, Error::UndefinedCondition, QStringLiteral("Server returned invalid data form."));
+ return QXmppError { QStringLiteral("Server returned invalid data form."), {} };
}
- return Error(Error::Cancel, Error::UndefinedCondition, QStringLiteral("Server returned no data form."));
+ return QXmppError { QStringLiteral("Server returned no data form."), {} };
});
}
diff --git a/src/client/QXmppPubSubManager.h b/src/client/QXmppPubSubManager.h
index 4e5ab9f8..73a5b4d4 100644
--- a/src/client/QXmppPubSubManager.h
+++ b/src/client/QXmppPubSubManager.h
@@ -52,21 +52,21 @@ public:
std::optional<QXmppResultSetReply> continuation;
};
- using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
- using FeaturesResult = std::variant<QVector<QString>, InvalidServiceType, QXmppStanza::Error>;
- using NodesResult = std::variant<QVector<QString>, QXmppStanza::Error>;
- using InstantNodeResult = std::variant<QString, QXmppStanza::Error>;
+ using Result = std::variant<QXmpp::Success, QXmppError>;
+ using FeaturesResult = std::variant<QVector<QString>, InvalidServiceType, QXmppError>;
+ using NodesResult = std::variant<QVector<QString>, QXmppError>;
+ using InstantNodeResult = std::variant<QString, QXmppError>;
template<typename T>
- using ItemResult = std::variant<T, QXmppStanza::Error>;
+ using ItemResult = std::variant<T, QXmppError>;
template<typename T>
- using ItemsResult = std::variant<Items<T>, QXmppStanza::Error>;
- using ItemIdsResult = std::variant<QVector<QString>, QXmppStanza::Error>;
- using PublishItemResult = std::variant<QString, QXmppStanza::Error>;
- using PublishItemsResult = std::variant<QVector<QString>, QXmppStanza::Error>;
- using SubscriptionsResult = std::variant<QVector<QXmppPubSubSubscription>, QXmppStanza::Error>;
- using AffiliationsResult = std::variant<QVector<QXmppPubSubAffiliation>, QXmppStanza::Error>;
- using OptionsResult = std::variant<QXmppPubSubSubscribeOptions, QXmppStanza::Error>;
- using NodeConfigResult = std::variant<QXmppPubSubNodeConfig, QXmppStanza::Error>;
+ using ItemsResult = std::variant<Items<T>, QXmppError>;
+ using ItemIdsResult = std::variant<QVector<QString>, QXmppError>;
+ using PublishItemResult = std::variant<QString, QXmppError>;
+ using PublishItemsResult = std::variant<QVector<QString>, QXmppError>;
+ using SubscriptionsResult = std::variant<QVector<QXmppPubSubSubscription>, QXmppError>;
+ using AffiliationsResult = std::variant<QVector<QXmppPubSubAffiliation>, QXmppError>;
+ using OptionsResult = std::variant<QXmppPubSubSubscribeOptions, QXmppError>;
+ using NodeConfigResult = std::variant<QXmppPubSubNodeConfig, QXmppError>;
QXmppPubSubManager();
~QXmppPubSubManager();
@@ -175,13 +175,12 @@ QXmppTask<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(con
const QString &itemId)
{
using namespace QXmpp::Private;
- using Error = QXmppStanza::Error;
return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), this,
[](PubSubIq<T> &&iq) -> ItemResult<T> {
if (!iq.items().isEmpty()) {
return iq.items().constFirst();
}
- return Error(Error::Cancel, Error::ItemNotFound, QStringLiteral("No such item has been found."));
+ return QXmppError { QStringLiteral("No such item has been found."), {} };
});
}
diff --git a/src/client/QXmppRosterManager.cpp b/src/client/QXmppRosterManager.cpp
index 87ebbd26..d3efadb4 100644
--- a/src/client/QXmppRosterManager.cpp
+++ b/src/client/QXmppRosterManager.cpp
@@ -14,6 +14,8 @@
#include <QDomElement>
+using namespace QXmpp::Private;
+
///
/// \fn QXmppRosterManager::subscriptionRequestReceived
///
@@ -307,9 +309,8 @@ QXmppTask<QXmppRosterManager::Result> QXmppRosterManager::renameRosterItem(const
{
using Error = QXmppStanza::Error;
if (!d->entries.contains(bareJid)) {
- return QXmpp::Private::makeReadyTask<Result>(
- Error(Error::Modify, Error::ItemNotFound,
- QStringLiteral("The roster doesn't contain this user.")));
+ return makeReadyTask<Result>(
+ QXmppError { QStringLiteral("The roster doesn't contain this user."), {} });
}
auto item = d->entries.value(bareJid);
diff --git a/src/client/QXmppRosterManager.h b/src/client/QXmppRosterManager.h
index f3629342..654de6eb 100644
--- a/src/client/QXmppRosterManager.h
+++ b/src/client/QXmppRosterManager.h
@@ -57,8 +57,8 @@ class QXMPP_EXPORT QXmppRosterManager : public QXmppClientExtension
Q_OBJECT
public:
- /// Empty result containing QXmpp::Success or a QXmppStanza::Error
- using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
+ /// Empty result containing QXmpp::Success or a QXmppError
+ using Result = std::variant<QXmpp::Success, QXmppError>;
QXmppRosterManager(QXmppClient *stream);
~QXmppRosterManager() override;
diff --git a/src/client/QXmppUploadRequestManager.cpp b/src/client/QXmppUploadRequestManager.cpp
index 4a45d86b..0e20a81c 100644
--- a/src/client/QXmppUploadRequestManager.cpp
+++ b/src/client/QXmppUploadRequestManager.cpp
@@ -236,9 +236,8 @@ auto QXmppUploadRequestManager::requestSlot(const QString &fileName,
const QString &uploadService) -> QXmppTask<SlotResult>
{
if (!serviceFound() && uploadService.isEmpty()) {
- using Error = QXmppStanza::Error;
- const auto errorMessage = QStringLiteral("Couldn't request upload slot: No service found.");
- return makeReadyTask(SlotResult(Error(Error::Cancel, Error::FeatureNotImplemented, errorMessage)));
+ return makeReadyTask(SlotResult(QXmppError {
+ QStringLiteral("Couldn't request upload slot: No service found."), {} }));
}
QXmppHttpUploadRequestIq iq;
diff --git a/src/client/QXmppUploadRequestManager.h b/src/client/QXmppUploadRequestManager.h
index e5ed752c..0cda7a55 100644
--- a/src/client/QXmppUploadRequestManager.h
+++ b/src/client/QXmppUploadRequestManager.h
@@ -5,7 +5,8 @@
#ifndef QXMPPUPLOADREQUESTMANAGER_H
#define QXMPPUPLOADREQUESTMANAGER_H
-#include <QXmppClientExtension.h>
+#include "QXmppError.h"
+#include "QXmppClientExtension.h"
#include <variant>
@@ -20,10 +21,11 @@ class QXmppHttpUploadSlotIq;
class QXmppUploadServicePrivate;
class QXmppUploadRequestManagerPrivate;
+///
/// \brief QXmppUploadService represents an HTTP File Upload service.
///
/// It is used to store the JID and maximum file size for uploads.
-
+///
class QXMPP_EXPORT QXmppUploadService
{
public:
@@ -97,7 +99,7 @@ public:
const QMimeType &mimeType,
const QString &uploadService = QString());
- using SlotResult = std::variant<QXmppHttpUploadSlotIq, QXmppStanza::Error>;
+ using SlotResult = std::variant<QXmppHttpUploadSlotIq, QXmppError>;
QXmppTask<SlotResult> requestSlot(const QFileInfo &file,
const QString &uploadService = {});
QXmppTask<SlotResult> requestSlot(const QFileInfo &file,
diff --git a/src/client/QXmppUserLocationManager.h b/src/client/QXmppUserLocationManager.h
index f9db4bc1..6d96e170 100644
--- a/src/client/QXmppUserLocationManager.h
+++ b/src/client/QXmppUserLocationManager.h
@@ -7,6 +7,7 @@
#define QXMPPUSERLOCATIONMANAGER_H
#include "QXmppClientExtension.h"
+#include "QXmppError.h"
#include "QXmppPubSubEventHandler.h"
#include <variant>
@@ -21,8 +22,8 @@ class QXMPP_EXPORT QXmppUserLocationManager : public QXmppClientExtension, publi
public:
using Item = QXmppGeolocItem;
- using GetResult = std::variant<Item, QXmppStanza::Error>;
- using PublishResult = std::variant<QString, QXmppStanza::Error>;
+ using GetResult = std::variant<Item, QXmppError>;
+ using PublishResult = std::variant<QString, QXmppError>;
QXmppUserLocationManager();
diff --git a/src/client/QXmppUserTuneManager.h b/src/client/QXmppUserTuneManager.h
index 90bc2d25..c1cbc795 100644
--- a/src/client/QXmppUserTuneManager.h
+++ b/src/client/QXmppUserTuneManager.h
@@ -6,6 +6,7 @@
#define QXMPPUSERTUNEMANAGER_H
#include "QXmppClientExtension.h"
+#include "QXmppError.h"
#include "QXmppPubSubEventHandler.h"
#include <variant>
@@ -20,8 +21,8 @@ class QXMPP_EXPORT QXmppUserTuneManager : public QXmppClientExtension, public QX
public:
using Item = QXmppTuneItem;
- using GetResult = std::variant<Item, QXmppStanza::Error>;
- using PublishResult = std::variant<QString, QXmppStanza::Error>;
+ using GetResult = std::variant<Item, QXmppError>;
+ using PublishResult = std::variant<QString, QXmppError>;
QXmppUserTuneManager();
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;