Make QDBusPendingReply behave like QDBusReply when dealing with errors

QDBusReply allows one to extract a QVariant and the type reply from an
error reply and getting a default-constructed value. This is useful when
a valid reply can never contain the default-constructed value (0, false,
empty strings, empty arrays, etc.), so it simplifies error checking.

More importantly, qdbusxml2cpp was changed a while ago from generating
QDBusReply to generating QDBusPendingReply, so we need to have the same
behavior.

Task-number: QTBUG-29046
Change-Id: Ia873b9fd4311c0d4e94f0ef623ba405c20bc0e8c
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Thiago Macieira 2013-01-11 11:25:28 -08:00 committed by The Qt Project
parent 9110d4f1ed
commit dc131e3a53
3 changed files with 30 additions and 9 deletions

View File

@ -185,6 +185,11 @@
function's return value is undefined (will probably cause an
assertion failure), so it is important to verify that the
processing is finished and the reply is valid.
If the reply does not contain an argument at position \a index or if the
reply was an error, this function returns an invalid QVariant. Since D-Bus
messages can never contain invalid QVariants, this return can be used to
detect an error condition.
*/
/*!
@ -197,6 +202,11 @@
Note that, if the reply hasn't arrived, this function causes the
calling thread to block until the reply is processed.
If the reply does not contain an argument at position \c Index or if the
reply was an error, this function returns a \c Type object that is default
constructed, which may be indistinguishable from a valid value. To reliably
determine whether the message was an error, use isError().
*/
/*!
@ -211,6 +221,10 @@
Note that, if the reply hasn't arrived, this function causes the
calling thread to block until the reply is processed.
If the reply is an error reply, this function returns a default-constructed
\c T1 object, which may be indistinguishable from a valid value. To
reliably determine whether the message was an error, use isError().
*/
/*!
@ -225,6 +239,10 @@
Note that, if the reply hasn't arrived, this function causes the
calling thread to block until the reply is processed.
If the reply is an error reply, this function returns a default-constructed
\c T1 object, which may be indistinguishable from a valid value. To
reliably determine whether the message was an error, use isError().
*/
/*!
@ -260,14 +278,12 @@ void QDBusPendingReplyData::assign(const QDBusMessage &message)
QVariant QDBusPendingReplyData::argumentAt(int index) const
{
if (d)
d->waitForFinished(); // bypasses "const"
if (!d)
return QVariant();
Q_ASSERT_X(d && index >= 0 && index < d->replyMessage.arguments().count(),
"QDBusPendingReply::argumentAt",
"Index out of bounds");
d->waitForFinished(); // bypasses "const"
return d->replyMessage.arguments().at(index);
return d->replyMessage.arguments().value(index);
}
void QDBusPendingReplyData::setMetaTypes(int count, const int *types)

View File

@ -168,9 +168,7 @@ public:
template<int Index> inline
const typename Select<Index>::Type argumentAt() const
{
// static assert?
Q_ASSERT_X(Index < count() && Index >= 0, "QDBusPendingReply::argumentAt",
"Index out of bounds");
Q_STATIC_ASSERT_X(Index >= 0 && Index < Count, "Index out of bounds");
typedef typename Select<Index>::Type ResultType;
return qdbus_cast<ResultType>(argumentAt(Index), 0);
}

View File

@ -572,6 +572,8 @@ void tst_QDBusPendingReply::errors()
QVERIFY(rint.isError());
error = rint.error();
VERIFY_ERROR(error);
int dummyint = rint;
QCOMPARE(dummyint, int());
QDBusPendingReply<int,int> rintint(iface->asyncCall("sendError"));
rintint.waitForFinished();
@ -579,6 +581,9 @@ void tst_QDBusPendingReply::errors()
QVERIFY(rintint.isError());
error = rintint.error();
VERIFY_ERROR(error);
dummyint = rintint;
QCOMPARE(dummyint, int());
QCOMPARE(rintint.argumentAt<1>(), int());
QDBusPendingReply<QString> rstring(iface->asyncCall("sendError"));
rstring.waitForFinished();
@ -586,6 +591,8 @@ void tst_QDBusPendingReply::errors()
QVERIFY(rstring.isError());
error = rstring.error();
VERIFY_ERROR(error);
QString dummystring = rstring;
QCOMPARE(dummystring, QString());
}
QTEST_MAIN(tst_QDBusPendingReply)