message: Add error handling to sd_bus_message calls

Previously, any errors decoding messages could cause the application to
just crash instead of being able to handle the exception. The
sd_bus_message methods provide error statuses that were just being
thrown away. Make use of any returned error information to ensure
application correctness.

Change-Id: If9c04b1ce4f6e1f1f6ce441d02e3497fe47b7f3b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/sdbusplus/message/read.hpp b/sdbusplus/message/read.hpp
index b52267e..6ab6a00 100644
--- a/sdbusplus/message/read.hpp
+++ b/sdbusplus/message/read.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <tuple>
+#include <sdbusplus/exception.hpp>
 #include <sdbusplus/message/types.hpp>
 #include <sdbusplus/utility/type_traits.hpp>
 #include <sdbusplus/utility/tuple_to_array.hpp>
@@ -130,7 +131,12 @@
                       "Non-basic types are not allowed.");
 
         constexpr auto dbusType = std::get<0>(types::type_id<T>());
-        intf->sd_bus_message_read_basic(m, dbusType, &t);
+        int r = intf->sd_bus_message_read_basic(m, dbusType, &t);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_read_basic fundamental");
+        }
     }
 };
 
@@ -145,7 +151,11 @@
     {
         constexpr auto dbusType = std::get<0>(types::type_id<T>());
         const char* str = nullptr;
-        intf->sd_bus_message_read_basic(m, dbusType, &str);
+        int r = intf->sd_bus_message_read_basic(m, dbusType, &str);
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r, "sd_bus_message_read_basic string");
+        }
         s = str;
     }
 };
@@ -158,7 +168,12 @@
     {
         constexpr auto dbusType = std::get<0>(types::type_id<S>());
         const char* str = nullptr;
-        intf->sd_bus_message_read_basic(m, dbusType, &str);
+        int r = intf->sd_bus_message_read_basic(m, dbusType, &str);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_read_basic string_wrapper");
+        }
         s.str = str;
     }
 };
@@ -171,7 +186,11 @@
     {
         constexpr auto dbusType = std::get<0>(types::type_id<T>());
         int i = 0;
-        intf->sd_bus_message_read_basic(m, dbusType, &i);
+        int r = intf->sd_bus_message_read_basic(m, dbusType, &i);
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r, "sd_bus_message_read_basic bool");
+        }
         b = (i != 0);
     }
 };
@@ -185,17 +204,32 @@
     static void op(sdbusplus::SdBusInterface* intf, sd_bus_message* m, S&& s)
     {
         constexpr auto dbusType = utility::tuple_to_array(types::type_id<T>());
-        intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
-                                             dbusType.data() + 1);
+        int r = intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
+                                                     dbusType.data() + 1);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_enter_container emplace_back_container");
+        }
 
-        while (!intf->sd_bus_message_at_end(m, false))
+        while (!(r = intf->sd_bus_message_at_end(m, false)))
         {
             types::details::type_id_downcast_t<typename T::value_type> t;
             sdbusplus::message::read(intf, m, t);
             s.emplace_back(std::move(t));
         }
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_at_end emplace_back_container");
+        }
 
-        intf->sd_bus_message_exit_container(m);
+        r = intf->sd_bus_message_exit_container(m);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_exit_container emplace_back_container");
+        }
     }
 };
 
@@ -207,17 +241,32 @@
     static void op(sdbusplus::SdBusInterface* intf, sd_bus_message* m, S&& s)
     {
         constexpr auto dbusType = utility::tuple_to_array(types::type_id<T>());
-        intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
-                                             dbusType.data() + 1);
+        int r = intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY,
+                                                     dbusType.data() + 1);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_enter_container emplace_container");
+        }
 
-        while (!intf->sd_bus_message_at_end(m, false))
+        while (!(r = intf->sd_bus_message_at_end(m, false)))
         {
             types::details::type_id_downcast_t<typename T::value_type> t;
             sdbusplus::message::read(intf, m, t);
             s.emplace(std::move(t));
         }
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_at_end emplace_container");
+        }
 
-        intf->sd_bus_message_exit_container(m);
+        r = intf->sd_bus_message_exit_container(m);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_exit_container emplace_container");
+        }
     }
 };
 
@@ -230,10 +279,22 @@
         constexpr auto dbusType = utility::tuple_to_array(
             std::tuple_cat(types::type_id_nonull<T1>(), types::type_id<T2>()));
 
-        intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
-                                             dbusType.data());
+        int r = intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY,
+                                                     dbusType.data());
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r,
+                                        "sd_bus_message_enter_container pair");
+        }
+
         sdbusplus::message::read(intf, m, s.first, s.second);
-        intf->sd_bus_message_exit_container(m);
+
+        r = intf->sd_bus_message_exit_container(m);
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r,
+                                        "sd_bus_message_exit_container pair");
+        }
     }
 };
 
@@ -254,11 +315,23 @@
             types::type_id_nonull<Args...>(),
             std::make_tuple('\0') /* null terminator for C-string */));
 
-        intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT,
-                                             dbusType.data());
+        int r = intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT,
+                                                     dbusType.data());
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r,
+                                        "sd_bus_message_enter_container tuple");
+        }
+
         _op(intf, m, std::forward<S>(s),
             std::make_index_sequence<sizeof...(Args)>());
-        intf->sd_bus_message_exit_container(m);
+
+        r = intf->sd_bus_message_exit_container(m);
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r,
+                                        "sd_bus_message_exit_container tuple");
+        }
     }
 };
 
@@ -270,9 +343,14 @@
     {
         constexpr auto dbusType = utility::tuple_to_array(types::type_id<S1>());
 
-        auto rc = intf->sd_bus_message_verify_type(m, SD_BUS_TYPE_VARIANT,
-                                                   dbusType.data());
-        if (0 >= rc)
+        int r = intf->sd_bus_message_verify_type(m, SD_BUS_TYPE_VARIANT,
+                                                 dbusType.data());
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r,
+                                        "sd_bus_message_verify_type variant");
+        }
+        if (!r)
         {
             read<S, Args1...>(intf, m, s);
             return;
@@ -280,10 +358,22 @@
 
         std::remove_reference_t<S1> s1;
 
-        intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT,
-                                             dbusType.data());
+        r = intf->sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT,
+                                                 dbusType.data());
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_enter_container variant");
+        }
+
         sdbusplus::message::read(intf, m, s1);
-        intf->sd_bus_message_exit_container(m);
+
+        r = intf->sd_bus_message_exit_container(m);
+        if (r < 0)
+        {
+            throw exception::SdBusError(
+                -r, "sd_bus_message_exit_container variant");
+        }
 
         s = std::move(s1);
     }
@@ -291,7 +381,11 @@
     template <typename S>
     static void read(sdbusplus::SdBusInterface* intf, sd_bus_message* m, S&& s)
     {
-        intf->sd_bus_message_skip(m, "v");
+        int r = intf->sd_bus_message_skip(m, "v");
+        if (r < 0)
+        {
+            throw exception::SdBusError(-r, "sd_bus_message_skip variant");
+        }
         s = std::remove_reference_t<S>{};
     }