[Telepathy-commits] [telepathy-qt4/master] ReadinessHelper: Propagate error message when a feature fails introspection.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Fri Mar 6 11:28:12 PST 2009
---
TelepathyQt4/Client/account.cpp | 7 +-
TelepathyQt4/Client/connection-manager.cpp | 4 +-
TelepathyQt4/Client/connection.cpp | 10 +--
TelepathyQt4/Client/readiness-helper.cpp | 102 ++++++++++++++++++++++-----
TelepathyQt4/Client/readiness-helper.h | 14 +++-
TelepathyQt4/Client/text-channel.cpp | 6 +-
6 files changed, 107 insertions(+), 36 deletions(-)
diff --git a/TelepathyQt4/Client/account.cpp b/TelepathyQt4/Client/account.cpp
index d605ad6..dde67de 100644
--- a/TelepathyQt4/Client/account.cpp
+++ b/TelepathyQt4/Client/account.cpp
@@ -993,7 +993,7 @@ void Account::gotMainProperties(QDBusPendingCallWatcher *watcher)
debug() << "Account basic functionality is ready";
mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
} else {
- mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false, reply.error());
warning().nospace() <<
"GetAll(Account) failed: " <<
@@ -1021,7 +1021,7 @@ void Account::gotAvatar(QDBusPendingCallWatcher *watcher)
// check if the feature is already there, and for some reason retrieveAvatar
// failed when called the second time
if (!mPriv->readinessHelper->missingFeatures().contains(FeatureAvatar)) {
- mPriv->readinessHelper->setIntrospectCompleted(FeatureAvatar, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureAvatar, false, reply.error());
}
warning().nospace() <<
@@ -1056,7 +1056,8 @@ void Account::onConnectionManagerReady(PendingOperation *operation)
mPriv->readinessHelper->setIntrospectCompleted(FeatureProtocolInfo, true);
}
else {
- mPriv->readinessHelper->setIntrospectCompleted(FeatureProtocolInfo, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureProtocolInfo, false,
+ operation->errorName(), operation->errorMessage());
}
}
diff --git a/TelepathyQt4/Client/connection-manager.cpp b/TelepathyQt4/Client/connection-manager.cpp
index 82f67a4..15e4f89 100644
--- a/TelepathyQt4/Client/connection-manager.cpp
+++ b/TelepathyQt4/Client/connection-manager.cpp
@@ -667,7 +667,7 @@ void ConnectionManager::gotProtocols(QDBusPendingCallWatcher *watcher)
mPriv->introspectParameters();
} else {
- mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false, reply.error());
warning().nospace() <<
"ConnectionManager.ListProtocols failed: " <<
@@ -706,7 +706,7 @@ void ConnectionManager::gotParameters(QDBusPendingCallWatcher *watcher)
mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
} else {
// we could not retrieve the params for any protocol, fail core.
- mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false, reply.error());
}
#if 0
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index 1bbda28..4662bc7 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -803,9 +803,6 @@ void Connection::gotStatus(QDBusPendingCallWatcher *watcher)
reply.error().name() << ":" << reply.error().message();
invalidate(reply.error());
-
- // introspect core failed
- mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false);
return;
}
@@ -889,7 +886,8 @@ void Connection::gotSelfContact(PendingOperation *op)
// check if the feature is already there, and for some reason introspectSelfContact
// failed when called the second time
if (!mPriv->readinessHelper->missingFeatures().contains(FeatureSelfContact)) {
- mPriv->readinessHelper->setIntrospectCompleted(FeatureSelfContact, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureSelfContact, false,
+ op->errorName(), op->errorMessage());
}
}
}
@@ -906,7 +904,7 @@ void Connection::gotSimpleStatuses(QDBusPendingCallWatcher *watcher)
else {
warning().nospace() << "Getting simple presence statuses failed with " <<
reply.error().name() << ":" << reply.error().message();
- mPriv->readinessHelper->setIntrospectCompleted(FeatureSimplePresence, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureSimplePresence, false, reply.error());
}
watcher->deleteLater();
@@ -928,7 +926,7 @@ void Connection::gotSelfHandle(QDBusPendingCallWatcher *watcher)
} else {
warning().nospace() << "Getting self handle failed with " <<
reply.error().name() << ":" << reply.error().message();
- mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false, reply.error());
}
watcher->deleteLater();
diff --git a/TelepathyQt4/Client/readiness-helper.cpp b/TelepathyQt4/Client/readiness-helper.cpp
index 999f103..4115e85 100644
--- a/TelepathyQt4/Client/readiness-helper.cpp
+++ b/TelepathyQt4/Client/readiness-helper.cpp
@@ -28,6 +28,7 @@
#include <TelepathyQt4/Client/PendingReady>
#include <TelepathyQt4/Constants>
+#include <QDBusError>
#include <QTimer>
namespace Telepathy
@@ -44,7 +45,9 @@ struct ReadinessHelper::Private
~Private();
void setCurrentStatus(uint newStatus);
- void setIntrospectCompleted(const Feature &feature, bool success);
+ void setIntrospectCompleted(const Feature &feature, bool success,
+ const QString &errorName = QString(),
+ const QString &errorMessage = QString());
void iterateIntrospection();
void abortOperations(const QString &errorName, const QString &errorMessage);
@@ -61,6 +64,7 @@ struct ReadinessHelper::Private
Features missingFeatures;
Features pendingFeatures;
Features inFlightFeatures;
+ QHash<Feature, QPair<QString, QString> > missingFeaturesErrors;
QList<PendingReady *> pendingOperations;
bool pendingStatusChange;
@@ -121,7 +125,8 @@ void ReadinessHelper::Private::setCurrentStatus(uint newStatus)
}
}
-void ReadinessHelper::Private::setIntrospectCompleted(const Feature &feature, bool success)
+void ReadinessHelper::Private::setIntrospectCompleted(const Feature &feature,
+ bool success, const QString &errorName, const QString &errorMessage)
{
debug() << "ReadinessHelper::setIntrospectCompleted: feature:" << feature <<
"- success:" << success;
@@ -148,6 +153,12 @@ void ReadinessHelper::Private::setIntrospectCompleted(const Feature &feature, bo
}
else {
missingFeatures.insert(feature);
+ missingFeaturesErrors.insert(feature,
+ QPair<QString, QString>(errorName, errorMessage));
+ if (errorName.isEmpty()) {
+ warning() << "ReadinessHelper::setIntrospectCompleted: Feature" <<
+ feature << "introspection failed but no error message was given";
+ }
}
pendingFeatures.remove(feature);
@@ -177,7 +188,10 @@ void ReadinessHelper::Private::iterateIntrospection()
Introspectable introspectable = i.value();
Features dependsOnFeatures = introspectable.dependsOnFeatures;
if (!dependsOnFeatures.intersect(missingFeatures).isEmpty()) {
- missingFeatures += feature;
+ missingFeatures.insert(feature);
+ missingFeaturesErrors.insert(feature,
+ QPair<QString, QString>(TELEPATHY_ERROR_NOT_AVAILABLE,
+ "Feature depend on other features that are not available"));
}
++i;
}
@@ -185,15 +199,14 @@ void ReadinessHelper::Private::iterateIntrospection()
// check if any pending operations for becomeReady should finish now
// based on their requested features having nothing more than what
// satisfiedFeatures + missingFeatures has
+ QString errorName;
+ QString errorMessage;
foreach (PendingReady *operation, pendingOperations) {
if ((operation->requestedFeatures() - (satisfiedFeatures + missingFeatures)).isEmpty()) {
- if (parent->isReady(operation->requestedFeatures())) {
+ if (parent->isReady(operation->requestedFeatures(), &errorName, &errorMessage)) {
operation->setFinished();
} else {
- // TODO get the error from somewhere, maybe add an error param
- // to setIntrospectCompleted
- operation->setFinishedWithError(TELEPATHY_ERROR_NOT_AVAILABLE,
- "Some features not available");
+ operation->setFinishedWithError(errorName, errorMessage);
}
pendingOperations.removeOne(operation);
}
@@ -243,7 +256,9 @@ void ReadinessHelper::Private::iterateIntrospection()
debug() << "feature" << feature << "depends on interfaces" <<
introspectable.dependsOnInterfaces << ", but interface" << interface <<
"is not present";
- setIntrospectCompleted(feature, false);
+ setIntrospectCompleted(feature, false,
+ QLatin1String(TELEPATHY_ERROR_NOT_AVAILABLE),
+ QLatin1String("Feature depend on interfaces that are not available"));
return; // will be called with a single-shot soon again
}
}
@@ -260,6 +275,7 @@ void ReadinessHelper::Private::abortOperations(const QString &errorName,
{
foreach (PendingReady *operation, pendingOperations) {
operation->setFinishedWithError(errorName, errorMessage);
+ pendingOperations.removeOne(operation);
}
}
@@ -341,37 +357,73 @@ Features ReadinessHelper::missingFeatures() const
return mPriv->missingFeatures;
}
-bool ReadinessHelper::isReady(const Feature &feature) const
+bool ReadinessHelper::isReady(const Feature &feature,
+ QString *errorName, QString *errorMessage) const
{
if (!mPriv->proxy->isValid()) {
+ if (errorName) {
+ *errorName = mPriv->proxy->invalidationReason();
+ }
+ if (errorMessage) {
+ *errorMessage = mPriv->proxy->invalidationMessage();
+ }
+ return false;
+ }
+
+ if (!mPriv->supportedFeatures.contains(feature)) {
+ if (errorName) {
+ *errorName = QLatin1String(TELEPATHY_ERROR_INVALID_ARGUMENT);
+ }
+ if (errorMessage) {
+ *errorMessage = QLatin1String("Unsupported feature");
+ }
return false;
}
+ bool ret = true;
+
if (feature.isCritical()) {
if (!mPriv->satisfiedFeatures.contains(feature)) {
debug() << "ReadinessHelper::isReady: critical feature" << feature << "not ready";
- return false;
+ ret = false;
}
} else {
if (!mPriv->satisfiedFeatures.contains(feature) &&
!mPriv->missingFeatures.contains(feature)) {
debug() << "ReadinessHelper::isReady: feature" << feature << "not ready";
- return false;
+ ret = false;
}
}
- return true;
+
+ if (!ret) {
+ QPair<QString, QString> error = mPriv->missingFeaturesErrors[feature];
+ if (errorName) {
+ *errorName = error.first;
+ }
+ if (errorMessage) {
+ *errorMessage = error.second;
+ }
+ }
+
+ return ret;
}
-bool ReadinessHelper::isReady(const Features &features) const
+bool ReadinessHelper::isReady(const Features &features, QString *errorName, QString *errorMessage) const
{
if (!mPriv->proxy->isValid()) {
+ if (errorName) {
+ *errorName = mPriv->proxy->invalidationReason();
+ }
+ if (errorMessage) {
+ *errorMessage = mPriv->proxy->invalidationMessage();
+ }
return false;
}
Q_ASSERT(!features.isEmpty());
foreach (const Feature &feature, features) {
- if (!isReady(feature)) {
+ if (!isReady(feature, errorName, errorMessage)) {
return false;
}
}
@@ -388,8 +440,9 @@ PendingReady *ReadinessHelper::becomeReady(const Features &requestedFeatures)
requestedFeatures << "- supportedFeatures =" << mPriv->supportedFeatures;
PendingReady *operation =
new PendingReady(requestedFeatures, mPriv->proxy);
- operation->setFinishedWithError(TELEPATHY_ERROR_INVALID_ARGUMENT,
- "Requested features contains invalid feature");
+ operation->setFinishedWithError(
+ QLatin1String(TELEPATHY_ERROR_INVALID_ARGUMENT),
+ QLatin1String("Requested features contains unsupported feature"));
return operation;
}
@@ -420,13 +473,20 @@ PendingReady *ReadinessHelper::becomeReady(const Features &requestedFeatures)
return operation;
}
-void ReadinessHelper::setIntrospectCompleted(const Feature &feature, bool success)
+void ReadinessHelper::setIntrospectCompleted(const Feature &feature, bool success,
+ const QString &errorName, const QString &errorMessage)
{
if (!mPriv->proxy->isValid()) {
// proxy became invalid, ignore here
return;
}
- mPriv->setIntrospectCompleted(feature, success);
+ mPriv->setIntrospectCompleted(feature, success, errorName, errorMessage);
+}
+
+void ReadinessHelper::setIntrospectCompleted(const Feature &feature, bool success,
+ const QDBusError &error)
+{
+ setIntrospectCompleted(feature, success, error.name(), error.message());
}
void ReadinessHelper::iterateIntrospection()
@@ -437,6 +497,10 @@ void ReadinessHelper::iterateIntrospection()
void ReadinessHelper::onProxyInvalidated(Telepathy::Client::DBusProxy *proxy,
const QString &errorName, const QString &errorMessage)
{
+ // clear satisfied and missing features as we have public methods to get them
+ mPriv->satisfiedFeatures.clear();
+ mPriv->missingFeatures.clear();
+
mPriv->abortOperations(errorName, errorMessage);
}
diff --git a/TelepathyQt4/Client/readiness-helper.h b/TelepathyQt4/Client/readiness-helper.h
index 5f5ec43..201cb13 100644
--- a/TelepathyQt4/Client/readiness-helper.h
+++ b/TelepathyQt4/Client/readiness-helper.h
@@ -33,6 +33,8 @@
#include <QSet>
#include <QStringList>
+class QDBusError;
+
namespace Telepathy
{
namespace Client
@@ -100,11 +102,17 @@ public:
Features actualFeatures() const;
Features missingFeatures() const;
- bool isReady(const Feature &feature) const;
- bool isReady(const Features &features) const;
+ bool isReady(const Feature &feature,
+ QString *errorName = 0, QString *errorMessage = 0) const;
+ bool isReady(const Features &features,
+ QString *errorName = 0, QString *errorMessage = 0) const;
PendingReady *becomeReady(const Features &requestedFeatures);
- void setIntrospectCompleted(const Feature &feature, bool success);
+ void setIntrospectCompleted(const Feature &feature, bool success,
+ const QString &errorName = QString(),
+ const QString &errorMessage = QString());
+ void setIntrospectCompleted(const Feature &feature, bool success,
+ const QDBusError &error);
Q_SIGNALS:
void statusReady(uint status);
diff --git a/TelepathyQt4/Client/text-channel.cpp b/TelepathyQt4/Client/text-channel.cpp
index 72a627f..37162cb 100644
--- a/TelepathyQt4/Client/text-channel.cpp
+++ b/TelepathyQt4/Client/text-channel.cpp
@@ -953,12 +953,12 @@ void TextChannel::gotProperties(QDBusPendingCallWatcher *watcher)
ReadinessHelper *readinessHelper = mPriv->readinessHelper;
if (readinessHelper->requestedFeatures().contains(FeatureMessageQueue) &&
!readinessHelper->isReady(Features() << FeatureMessageQueue)) {
- readinessHelper->setIntrospectCompleted(FeatureMessageQueue, false);
+ readinessHelper->setIntrospectCompleted(FeatureMessageQueue, false, reply.error());
}
if (readinessHelper->requestedFeatures().contains(FeatureMessageCapabilities) &&
!readinessHelper->isReady(Features() << FeatureMessageCapabilities)) {
- readinessHelper->setIntrospectCompleted(FeatureMessageCapabilities, false);
+ readinessHelper->setIntrospectCompleted(FeatureMessageCapabilities, false, reply.error());
}
return;
}
@@ -982,7 +982,7 @@ void TextChannel::gotPendingMessages(QDBusPendingCallWatcher *watcher)
reply.error().message();
// TODO should we fail here?
- mPriv->readinessHelper->setIntrospectCompleted(FeatureMessageQueue, false);
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureMessageQueue, false, reply.error());
return;
}
--
1.5.6.5
More information about the telepathy-commits
mailing list