Redesigned error handling

Current error handling send only error code, which is not enough to
display detailed information. New error handling in additional to
error code send property name. This allows to send meaningful messages
back to used about errors.

Tested:
  - Old redfish code properly handles errors (reads only error_code)
  - Redfish version which read property name from error displays more
    detailed error information

Change-Id: I54caa20881ac3f3e38cb295a3aa95ddab491303f
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/utils/conversion.hpp b/src/utils/conversion.hpp
index fd3dbcb..e92249a 100644
--- a/src/utils/conversion.hpp
+++ b/src/utils/conversion.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "errors.hpp"
+
 #include <sdbusplus/exception.hpp>
 
 #include <algorithm>
@@ -10,24 +12,40 @@
 namespace utils
 {
 
-template <class T>
-struct EnumTraits
+template <size_t N>
+struct ConstexprString
 {
-    [[noreturn]] static void throwConversionError()
+    constexpr ConstexprString(const char (&data)[N]) : s()
     {
-        throw sdbusplus::exception::SdBusError(
-            static_cast<int>(std::errc::invalid_argument),
-            "Invalid enum value");
+        for (size_t i = 0; i < N; ++i)
+        {
+            s[i] = data[i];
+        }
     }
+
+    constexpr operator std::string_view() const
+    {
+        return {s.data(), s.size()};
+    }
+
+    std::array<char, N> s;
 };
 
+[[noreturn]] inline void throwConversionError(std::string_view propertyName)
+{
+    throw errors::InvalidArgument(propertyName, "Cannot convert.");
+}
+
+template <class T>
+struct EnumTraits;
+
 template <class T, T first, T last>
 inline T toEnum(std::underlying_type_t<T> x)
 {
     if (x < static_cast<std::underlying_type_t<T>>(first) ||
         x > static_cast<std::underlying_type_t<T>>(last))
     {
-        EnumTraits<T>::throwConversionError();
+        throwConversionError(EnumTraits<T>::propertyName);
     }
     return static_cast<T>(x);
 }
@@ -77,7 +95,7 @@
         [&value](const auto& item) { return item.first == value; });
     if (it == std::end(data))
     {
-        EnumTraits<T>::throwConversionError();
+        throwConversionError(EnumTraits<T>::propertyName);
     }
     return it->second;
 }
@@ -92,7 +110,7 @@
         [value](const auto& item) { return item.second == value; });
     if (it == std::end(data))
     {
-        EnumTraits<T>::throwConversionError();
+        throwConversionError(EnumTraits<T>::propertyName);
     }
     return it->first;
 }
diff --git a/src/utils/dbus_path_utils.cpp b/src/utils/dbus_path_utils.cpp
index 5c1fddb..2eabc86 100644
--- a/src/utils/dbus_path_utils.cpp
+++ b/src/utils/dbus_path_utils.cpp
@@ -51,23 +51,17 @@
     {
         if (pos_start == pos_end)
         {
-            throw sdbusplus::exception::SdBusError(
-                static_cast<int>(std::errc::invalid_argument),
-                "Invalid prefixes in id");
+            throw errors::InvalidArgument("Id", "Invalid prefixes in id.");
         }
 
         if (++prefix_cnt > constants::maxPrefixesInId)
         {
-            throw sdbusplus::exception::SdBusError(
-                static_cast<int>(std::errc::invalid_argument),
-                "Too many prefixes");
+            throw errors::InvalidArgument("Id", "Too many prefixes.");
         }
 
         if (pos_end - pos_start > constants::maxPrefixLength)
         {
-            throw sdbusplus::exception::SdBusError(
-                static_cast<int>(std::errc::invalid_argument),
-                "Prefix too long");
+            throw errors::InvalidArgument("Id", "Prefix too long.");
         }
 
         pos_start = pos_end + 1;
@@ -75,8 +69,7 @@
 
     if (id.length() - pos_start > constants::maxIdNameLength)
     {
-        throw sdbusplus::exception::SdBusError(
-            static_cast<int>(std::errc::invalid_argument), "Id too long");
+        throw errors::InvalidArgument("Id", "Too long.");
     }
 }
 } // namespace utils
diff --git a/src/utils/dbus_path_utils.hpp b/src/utils/dbus_path_utils.hpp
index 3798d98..c1bda62 100644
--- a/src/utils/dbus_path_utils.hpp
+++ b/src/utils/dbus_path_utils.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "errors.hpp"
+
 #include <sdbusplus/message.hpp>
 
 #include <algorithm>
@@ -53,9 +55,7 @@
     if (id.find_first_not_of(utils::constants::allowedCharactersInPath) !=
         std::string::npos)
     {
-        throw sdbusplus::exception::SdBusError(
-            static_cast<int>(std::errc::invalid_argument),
-            "Invalid character in id");
+        throw errors::InvalidArgument("Id", "Invalid character.");
     }
 }
 
diff --git a/src/utils/make_id_name.cpp b/src/utils/make_id_name.cpp
index 0df6c17..1390dad 100644
--- a/src/utils/make_id_name.cpp
+++ b/src/utils/make_id_name.cpp
@@ -93,8 +93,7 @@
 {
     if (name.length() > constants::maxIdNameLength)
     {
-        throw sdbusplus::exception::SdBusError(
-            static_cast<int>(std::errc::invalid_argument), "Name too long");
+        throw errors::InvalidArgument("Name", "Too long.");
     }
 
     if (name.empty() && !id.ends_with('/'))