diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-09-06 20:05:34 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2022-09-09 22:49:06 +0200 |
| commit | b113ae300efe5dc17f148a06df09062546bf54ee (patch) | |
| tree | a7ada2bf208329687a7c4d47d74579551d9257a9 /src | |
| parent | 74cc77670b009ef98d681477ac430210d02c4cc4 (diff) | |
| download | qxmpp-b113ae300efe5dc17f148a06df09062546bf54ee.tar.gz | |
Add QXmppError holding a description and std::any
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/base/QXmppError.cpp | 75 | ||||
| -rw-r--r-- | src/base/QXmppError.h | 51 |
3 files changed, 128 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4164bd71..6723e081 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ set(INSTALL_HEADER_FILES base/QXmppE2eeMetadata.h base/QXmppElement.h base/QXmppEntityTimeIq.h + base/QXmppError.h base/QXmppExtension.h base/QXmppFutureUtils_p.h base/QXmppFileMetadata.h @@ -158,6 +159,7 @@ set(SOURCE_FILES base/QXmppDiscoveryIq.cpp base/QXmppElement.cpp base/QXmppEntityTimeIq.cpp + base/QXmppError.cpp base/QXmppFileMetadata.cpp base/QXmppGeolocItem.cpp base/QXmppGlobal.cpp diff --git a/src/base/QXmppError.cpp b/src/base/QXmppError.cpp new file mode 100644 index 00000000..80578c0d --- /dev/null +++ b/src/base/QXmppError.cpp @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppError.h" + +#include "QXmppStanza.h" + +#include <QFileDevice> +#include <QNetworkReply> + +/// +/// \class QXmppError +/// +/// Generic error class holding a description and a more specific error object. The specific error +/// usually is something like a QXmppStanza::Error or an enum. +/// +/// \since QXmpp 1.5 +/// + +/// +/// \var QXmppError::description +/// +/// Human readable description of the error. +/// + +/// +/// \var QXmppError::error +/// +/// More specific details on the error. It may be of any type. Functions returning QXmppError +/// should tell you which types are used. +/// + +/// +/// Returns whether the error is a QNetworkReply::NetworkError. +/// +bool QXmppError::isFileError() const +{ + return holdsType<QFileDevice::FileError>(); +} + +/// +/// Returns whether the error is a QNetworkReply::NetworkError. +/// +bool QXmppError::isNetworkError() const +{ + return holdsType<QNetworkReply::NetworkError>(); +} + +/// +/// Returns whether the error is a QXmppStanza::Error. +/// +bool QXmppError::isStanzaError() const +{ + return holdsType<QXmppStanza::Error>(); +} + +/// +/// \fn QXmppError::holdsType() +/// +/// Returns true if the error is of type T. +/// + +/// +/// \fn QXmppError::value() +/// +/// Copies the value if it has type T, returns empty optional otherwise. +/// + +/// +/// \fn QXmppError::takeValue() +/// +/// Moves out the value if it has type T, leaves the stored error intact and returns an empty +/// optional otherwise. +/// diff --git a/src/base/QXmppError.h b/src/base/QXmppError.h new file mode 100644 index 00000000..a646b6e5 --- /dev/null +++ b/src/base/QXmppError.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPERROR_H +#define QXMPPERROR_H + +#include "QXmppGlobal.h" + +#include <any> +#include <optional> + +struct QXMPP_EXPORT QXmppError +{ + QString description; + std::any error; + + bool isFileError() const; + bool isNetworkError() const; + bool isStanzaError() const; + + template<typename T> + bool holdsType() const + { + return error.type().hash_code() == typeid(T).hash_code(); + } + template<typename T> + std::optional<T> value() const + { + // any_cast always checks this, to avoid an additional check we use exceptions + try { + return std::any_cast<T>(error); + } catch (std::bad_any_cast) { + return {}; + } + } + template<typename T> + std::optional<T> takeValue() + { + // we can't use unchecked any_cast with moving because we can't access the error after a + // failed any_cast + if (error.type().hash_code() == typeid(T).hash_code()) { + auto value = std::any_cast<T>(std::move(error)); + error = std::any(); + return value; + } + return {}; + } +}; + +#endif // QXMPPERROR_H |
