diff --git a/dconfig-center/dde-dconfig-daemon/dconfig_global.h b/dconfig-center/dde-dconfig-daemon/dconfig_global.h index f2423a3..447589c 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfig_global.h +++ b/dconfig-center/dde-dconfig-daemon/dconfig_global.h @@ -28,6 +28,13 @@ using ConnRefCount = int; using ConfigCacheKey = QString; static constexpr int TestUid = 0U; static const QString VirtualInterAppId = "_"; +// Error name returned to clients when the requested configuration resource +// has no meta file installed. Clients may use it to demote this expected case +// (e.g. an optional component's configuration is not packaged) to debug +// output, while real load failures keep the generic Failed error. Keep in +// sync with dtkcore's src/dconfig.cpp. +static const QString ResourceNotFoundError = + QStringLiteral("org.desktopspec.ConfigManager.ResourceNotFound"); inline QString formatDBusObjectPath(QString path) { diff --git a/dconfig-center/dde-dconfig-daemon/dconfigresource.cpp b/dconfig-center/dde-dconfig-daemon/dconfigresource.cpp index 6295747..a0d187f 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfigresource.cpp +++ b/dconfig-center/dde-dconfig-daemon/dconfigresource.cpp @@ -245,6 +245,15 @@ DConfigFile *DSGConfigResource::getOrCreateFile(const QString &appid) return file.release(); } +bool DSGConfigResource::isMetaFileMissing(const QString &appid) const +{ + // Same lookup as getOrCreateFile(): a missing meta path means the resource + // was never installed, while a non-empty path with a failed load is a real + // failure (e.g. unparsable meta file) that must stay visible. + DConfigFile file(innerAppidToOuter(appid), m_fileName, m_subpath); + return file.meta()->metaPath(m_localPrefix).isEmpty(); +} + DConfigCache *DSGConfigResource::getOrCreateCache(const QString &appid, const uint uid) { const auto connKey = getConnectionKey(getResourceKey(appid, m_key), uid); diff --git a/dconfig-center/dde-dconfig-daemon/dconfigresource.h b/dconfig-center/dde-dconfig-daemon/dconfigresource.h index 4b68b68..34b1752 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfigresource.h +++ b/dconfig-center/dde-dconfig-daemon/dconfigresource.h @@ -32,6 +32,11 @@ class DSGConfigResource : public QObject bool load(const QString &appid); + // Tells whether no meta file is installed for the given appid using the + // same lookup as load(); used to distinguish "meta never installed" + // (expected) from real load failures (e.g. unparsable meta file). + bool isMetaFileMissing(const QString &appid) const; + GenericResourceKey key() const; DConfigFile *getFile(const ResourceKey &key) const; DConfigCache *getCache(const ConnKey &key) const; diff --git a/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp b/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp index 04e6e1b..e91430a 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp +++ b/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp @@ -284,8 +284,16 @@ QDBusObjectPath DSGConfigServer::acquireManagerV2(const uint &uid, const QString if (!loadStatus) { //error QString errorMsg = QString("Can't load resource: %1, for the appid:[%2].").arg(genericResourceKey).arg(appid); - if (calledFromDBus()) - sendErrorReply(QDBusError::Failed, errorMsg); + if (calledFromDBus()) { + // A missing meta file is an expected case (e.g. an optional + // component's configuration is not packaged); use a dedicated + // error name so clients can demote it to debug output. Real load + // failures keep the generic Failed error to stay visible. + if (resource->isMetaFileMissing(innerAppid)) + sendErrorReply(ResourceNotFoundError, errorMsg); + else + sendErrorReply(QDBusError::Failed, errorMsg); + } qWarning() << qPrintable(errorMsg); return QDBusObjectPath(); diff --git a/dconfig-center/tests/ut_dconfigserver.cpp b/dconfig-center/tests/ut_dconfigserver.cpp index d25ff1a..bb0c707 100644 --- a/dconfig-center/tests/ut_dconfigserver.cpp +++ b/dconfig-center/tests/ut_dconfigserver.cpp @@ -113,6 +113,21 @@ TEST_F(ut_DConfigServer, acquireManager) { ASSERT_EQ(server->resourceSize(), 1); } +TEST_F(ut_DConfigServer, isMetaFileMissing) { + // Meta file installed: not missing. + DSGConfigResource installed(FILE_NAME, QString(), LocalPrefix); + EXPECT_FALSE(installed.isMetaFileMissing(APP_ID)); + + // Meta file present but unparsable: still not "missing", so real load + // failures keep the generic Failed error and stay visible. + DSGConfigResource invalid("invalid", QString(), LocalPrefix); + EXPECT_FALSE(invalid.isMetaFileMissing("org.invalid.app")); + + // No meta file at all: expected case, reported as ResourceNotFound. + DSGConfigResource missing("example_noexist", QString(), LocalPrefix); + EXPECT_TRUE(missing.isMetaFileMissing(APP_ID)); +} + TEST_F(ut_DConfigServer, internalCatalog) { const auto catalog = server->internalCatalog(); ASSERT_TRUE(catalog);