diff options
author | Matt Spinler <spinler@us.ibm.com> | 2018-04-25 15:26:10 -0500 |
---|---|---|
committer | Matthew Barth <msbarth@us.ibm.com> | 2018-05-09 10:15:35 -0500 |
commit | ba7b5fea818f65949cd074de9322094d3c54fb7b (patch) | |
tree | 953b30c25fa2086bd56f2af340965adbd8244f55 /sdbusplus.hpp | |
parent | 84f105b7f83bcafc28f3b9c30592cd754af44719 (diff) | |
download | phosphor-fan-presence-ba7b5fea818f65949cd074de9322094d3c54fb7b.tar.gz phosphor-fan-presence-ba7b5fea818f65949cd074de9322094d3c54fb7b.zip |
Throw custom exceptions on D-Bus method failures
All 3 fan applications - control, monitor, and presence
have cases where it is expected that a getProperty call
may fail because a sensor is missing. While the applications
already handle this, the InternalFailure exception that was
being thrown by the underlying call generates log entries
that make it look like something bad happened.
The custom exceptions now being thrown do not log anything on
creation, but store all of the failing information so that
any callers could still log the info if they wanted to.
Tested: Boot a water cooled Witherspoon and see the fan presence
and monitor applications not look like they are
failing. Boot a system without the fan hwmon running,
and see fan-control-init still show the fails.
Change-Id: Ifd8ad6e3deb492bbaf33f12c7258125dce1e5ea8
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Diffstat (limited to 'sdbusplus.hpp')
-rw-r--r-- | sdbusplus.hpp | 116 |
1 files changed, 92 insertions, 24 deletions
diff --git a/sdbusplus.hpp b/sdbusplus.hpp index 454fde8..e977744 100644 --- a/sdbusplus.hpp +++ b/sdbusplus.hpp @@ -19,6 +19,74 @@ namespace detail namespace errors = sdbusplus::xyz::openbmc_project::Common::Error; } // namespace detail +/** + * @class DBusError + * + * The base class for the exceptions thrown on fails in the various + * SDBusPlus calls. Used so that a single catch statement can catch + * any type of these exceptions. + * + * None of these exceptions will log anything when they are created, + * it is up to the handler to do that if desired. + */ +class DBusError : public std::runtime_error +{ + public: + DBusError(const char* msg) : + std::runtime_error(msg) + { + } +}; + +/** + * @class DBusMethodError + * + * Thrown on a DBus Method call failure + */ +class DBusMethodError : public DBusError +{ + public: + DBusMethodError( + const std::string& busName, + const std::string& path, + const std::string& interface, + const std::string& method) : + DBusError("DBus method call failed"), + busName(busName), + path(path), + interface(interface), + method(method) + { + } + + const std::string busName; + const std::string path; + const std::string interface; + const std::string method; +}; + +/** + * @class DBusServiceError + * + * Thrown when a service lookup fails. Usually this points to + * the object path not being present in D-Bus. + */ +class DBusServiceError : public DBusError +{ + public: + DBusServiceError( + const std::string& path, + const std::string& interface) : + DBusError("DBus service lookup failed"), + path(path), + interface(interface) + { + } + + const std::string path; + const std::string interface; +}; + /** @brief Alias for PropertiesChanged signal callbacks. */ template <typename ...T> using Properties = std::map<std::string, sdbusplus::message::variant<T...>>; @@ -57,13 +125,7 @@ class SDBusPlus if (respMsg.is_method_error()) { - phosphor::logging::log<phosphor::logging::level::INFO>( - "Failed to invoke DBus method.", - phosphor::logging::entry("PATH=%s", path.c_str()), - phosphor::logging::entry( - "INTERFACE=%s", interface.c_str()), - phosphor::logging::entry("METHOD=%s", method.c_str())); - phosphor::logging::elog<detail::errors::InternalFailure>(); + throw DBusMethodError{busName, path, interface, method}; } return respMsg; @@ -176,25 +238,31 @@ class SDBusPlus using namespace std::literals::string_literals; using GetObject = std::map<std::string, std::vector<std::string>>; - auto mapperResp = callMethodAndRead<GetObject>( - bus, - "xyz.openbmc_project.ObjectMapper"s, - "/xyz/openbmc_project/object_mapper"s, - "xyz.openbmc_project.ObjectMapper"s, - "GetObject"s, - path, - GetObject::mapped_type{interface}); - - if (mapperResp.empty()) + try { - phosphor::logging::log<phosphor::logging::level::INFO>( - "Object not found.", - phosphor::logging::entry("PATH=%s", path.c_str()), - phosphor::logging::entry( - "INTERFACE=%s", interface.c_str())); - phosphor::logging::elog<detail::errors::InternalFailure>(); + auto mapperResp = callMethodAndRead<GetObject>( + bus, + "xyz.openbmc_project.ObjectMapper"s, + "/xyz/openbmc_project/object_mapper"s, + "xyz.openbmc_project.ObjectMapper"s, + "GetObject"s, + path, + GetObject::mapped_type{interface}); + + if (mapperResp.empty()) + { + //Should never happen. A missing object would fail + //in callMethodAndRead() + phosphor::logging::log<phosphor::logging::level::ERR>( + "Empty mapper response on service lookup"); + throw DBusServiceError{path, interface}; + } + return mapperResp.begin()->first; + } + catch (DBusMethodError& e) + { + throw DBusServiceError{path, interface}; } - return mapperResp.begin()->first; } /** @brief Get service from the mapper. */ |