monitor : do not trigger error when inventory unavailable

Under some startup scenarios, fan-monitor can start before the
InventoryManager service has populated inventory. This leads to
false-positives when marking fans non-functional.

This fix detects D-Bus exceptions and defaults the fans to functional.
They subscribe to the interfaces-added signal which will populate the
fans with correct values as soon as Inventory Manager completes startup.

Signed-off-by: Mike Capps <mikepcapps@gmail.com>
Change-Id: I14bff20da14cba3f5ef4b79763867b5cecab0267
diff --git a/monitor/fan.cpp b/monitor/fan.cpp
index 5f0414d..c5322b1 100644
--- a/monitor/fan.cpp
+++ b/monitor/fan.cpp
@@ -84,7 +84,16 @@
         (_numSensorFailsForNonFunc == 0) ||
         (countNonFunctionalSensors() < _numSensorFailsForNonFunc);
 
-    updateInventory(functionalState);
+    if (updateInventory(functionalState) && !functionalState)
+    {
+        // the inventory update threw an exception, possibly because D-Bus
+        // wasn't ready. Try to update sensors back to functional to avoid a
+        // false-alarm. They will be updated again from subscribing to the
+        // properties-changed event
+
+        for (auto& sensor : _sensors)
+            sensor->setFunctional(true);
+    }
 
 #ifndef MONITOR_USE_JSON
     // Check current tach state when entering monitor mode
@@ -406,21 +415,41 @@
     _system.fanStatusChange(*this);
 }
 
-void Fan::updateInventory(bool functional)
+bool Fan::updateInventory(bool functional)
 {
-    auto objectMap =
-        util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
-                              util::FUNCTIONAL_PROPERTY, functional);
-    auto response = util::SDBusPlus::lookupAndCallMethod(
-        _bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify", objectMap);
-    if (response.is_method_error())
+    bool dbusError = false;
+
+    try
     {
-        log<level::ERR>("Error in Notify call to update inventory");
-        return;
+        auto objectMap =
+            util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
+                                  util::FUNCTIONAL_PROPERTY, functional);
+
+        auto response = util::SDBusPlus::lookupAndCallMethod(
+            _bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify",
+            objectMap);
+
+        if (response.is_method_error())
+        {
+            log<level::ERR>("Error in Notify call to update inventory");
+
+            dbusError = true;
+        }
+    }
+    catch (const util::DBusError& e)
+    {
+        dbusError = true;
+
+        getLogger().log(
+            fmt::format("D-Bus Exception reading/updating inventory : {}",
+                        e.what()),
+            Logger::error);
     }
 
     // This will always track the current state of the inventory.
     _functional = functional;
+
+    return dbusError;
 }
 
 void Fan::presenceChanged(sdbusplus::message::message& msg)