Skip to content

Commit

Permalink
Stream/Client: IQ handling: Automatically parse stanza errors
Browse files Browse the repository at this point in the history
This changes the behaviour of the IQ handling. If an IQ response of type
error is received, the stanza error is parsed and returned as
QXmppError. This reduces the amout of further code on side of the user
(and makes the binaries smaller). It makes it impossible to parse the
rest of an error IQ though. However a function for that purpose may
still be added later.
  • Loading branch information
lnjX committed Feb 4, 2024
1 parent d62fec5 commit f9cd13a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
6 changes: 0 additions & 6 deletions src/base/QXmppFutureUtils_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,6 @@ auto parseIq(Input &&sendResult, Converter convert) -> decltype(convert({}))
[convert = std::move(convert)](const QDomElement &element) -> Result {
IqType iq;
iq.parse(element);
if (iq.type() == QXmppIq::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 {
Expand Down
22 changes: 19 additions & 3 deletions src/base/QXmppStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ QXmppStreamPrivate::~QXmppStreamPrivate()
///
/// \typedef QXmppStream::IqResult
///
/// Contains a QDomElement containing the IQ response or if the request couldn't
/// be sent a QXmpp::PacketState.
/// Contains a QDomElement if an IQ response of type 'result' has been received. In case of an
/// error response of if an error occurred while sending the IQ request, a QXmppError is used.
///
/// \warning THIS API IS NOT FINALIZED YET!
///
Expand Down Expand Up @@ -503,7 +503,23 @@ bool QXmppStream::handleIqResponse(const QDomElement &stanza)
return false;
}

itr.value().interface.finish(stanza);
// report IQ errors as QXmppError (this makes it impossible to parse the full error IQ,
// but that is okay for now)
if (iqType == QStringLiteral("error")) {
QXmppIq iq;
iq.parse(stanza);
if (auto err = iq.errorOptional()) {
// report stanza error
itr.value().interface.finish(QXmppError { err->text(), *err });
} else {
// this shouldn't happen (no <error/> element in IQ of type error)
using Err = QXmppStanza::Error;
itr.value().interface.finish(QXmppError { QStringLiteral("IQ error"), Err(Err::Cancel, Err::UndefinedCondition) });
}
} else {
// report stanza element for parsing
itr.value().interface.finish(stanza);
}

d->runningIqs.erase(itr);
return true;
Expand Down
12 changes: 9 additions & 3 deletions src/client/QXmppClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ bool process(QXmppClient *client, const QList<QXmppClientExtension *> &extension
///
/// \typedef QXmppClient::IqResult
///
/// Result of an IQ request, either contains the QDomElement of the IQ answer
/// (with type 'error' or 'result') or it contains the packet error, if the
/// request couldn't be sent.
/// Result of an IQ request, either contains the QDomElement of the IQ reponse (in case of an
/// 'result' IQ type) or it contains an QXmppError with a QXmppStanza::Error (on type 'error') or
/// a QXmpp::SendError.
///
/// \since QXmpp 1.5
///
Expand Down Expand Up @@ -496,6 +496,9 @@ QXmppTask<QXmpp::SendResult> QXmppClient::reply(QXmppStanza &&stanza, const std:
/// QDomElement. If you don't expect a special response, you may want use
/// sendGenericIq().
///
/// IQs of type 'error' are parsed automatically and returned as QXmppError with a contained
/// QXmppStanza::Error.
///
/// This does not do any end-to-encryption on the IQ.
///
/// \sa sendSensitiveIq()
Expand All @@ -518,6 +521,9 @@ QXmppTask<QXmppClient::IqResult> QXmppClient::sendIq(QXmppIq &&iq, const std::op
/// encrypted or it only makes little sense to do so. This is why the default
/// sendIq() does not do any additional end-to-end encryption.
///
/// IQs of type 'error' are parsed automatically and returned as QXmppError with a contained
/// QXmppStanza::Error.
///
/// \warning THIS API IS NOT FINALIZED YET!
///
/// \since QXmpp 1.5
Expand Down

0 comments on commit f9cd13a

Please sign in to comment.