Handle NotFound error for GetSubTreeById

Currently, PowerSupplies handling is done via `GetSubTreeById` and it
returns the success with the empty collection, even if the given chassis
is invalid.
```
GET /redfish/v1/Chassis/INVALID/PowerSubsystem/PowerSupplies
```

Once phosphor-objmgr is fixed by [1], the above URI will cause an
internalError.

This commit is to handle the case as NotFound error for the invalid
chassis with [1], and fixes the common error [2].

Tested:
- GET /redfish/v1/Chassis/INVALID/PowerSubsystem/PowerSupplies with
  NotFound.
- Redfish Service Validator passes

[1] https://gerrit.openbmc.org/c/openbmc/phosphor-objmgr/+/79311
[2] https://github.com/openbmc/bmcweb/blob/master/COMMON_ERRORS.md#11-not-responding-to-404

Change-Id: I1d2d19b7da6c0ad3b6a8d3090eb035732ec2e3ca
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp
index 09093a3..7316b5f 100644
--- a/redfish-core/lib/power_supply.hpp
+++ b/redfish-core/lib/power_supply.hpp
@@ -71,6 +71,12 @@
 {
     if (ec)
     {
+        if (ec.value() == boost::system::errc::io_error)
+        {
+            BMCWEB_LOG_WARNING("Chassis not found");
+            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+            return;
+        }
         if (ec.value() != EBADR)
         {
             BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
@@ -110,6 +116,7 @@
          chassisId](const std::optional<std::string>& validChassisPath) {
             if (!validChassisPath)
             {
+                BMCWEB_LOG_WARNING("Chassis not found");
                 messages::resourceNotFound(asyncResp->res, "Chassis",
                                            chassisId);
                 return;
@@ -164,11 +171,19 @@
 {
     if (ec)
     {
+        if (ec.value() == boost::system::errc::io_error)
+        {
+            // Not found
+            callback(std::string(), std::string());
+            return;
+        }
         if (ec.value() != EBADR)
         {
             BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
             messages::internalError(asyncResp->res);
+            return;
         }
+        callback(std::string(), std::string());
         return;
     }
     for (const auto& [objectPath, service] : subtree)
@@ -463,6 +478,14 @@
     const std::string& chassisId, const std::string& powerSupplyId,
     const std::string& powerSupplyPath, const std::string& service)
 {
+    if (powerSupplyPath.empty() || service.empty())
+    {
+        BMCWEB_LOG_WARNING("PowerSupply not found");
+        messages::resourceNotFound(asyncResp->res, "PowerSupply",
+                                   powerSupplyId);
+        return;
+    }
+
     asyncResp->res.addHeader(
         boost::beast::http::field::link,
         "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
@@ -497,7 +520,15 @@
     // Get the correct Path and Service that match the input parameters
     getValidPowerSupplyPath(
         asyncResp, chassisId, powerSupplyId,
-        [asyncResp](const std::string&, const std::string&) {
+        [asyncResp, powerSupplyId](const std::string& powerSupplyPath,
+                                   const std::string& service) {
+            if (powerSupplyPath.empty() || service.empty())
+            {
+                BMCWEB_LOG_WARNING("PowerSupply not found");
+                messages::resourceNotFound(asyncResp->res, "PowerSupply",
+                                           powerSupplyId);
+                return;
+            }
             asyncResp->res.addHeader(
                 boost::beast::http::field::link,
                 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");