Add non-throwing version of unpackProperties

Some projects (e.g., bmcweb) don't use functions which throw exceptions.
This change introduces unpackPropertiesNoThrow() function, which returns
optional string. In case of mismatched type or missing property, it will
contain its name. In case of no errors, std::nullopt will be returned.

As a side change, message returned by UnpackPropertyError::what() now
also includes propertyName and reason.

Testing done:
- Added unit tests for unpackPropertiesNoThrow().
- unpackProperties() functionality remained the same.

Signed-off-by: Szymon Dompke <szymon.dompke@intel.com>
Change-Id: I61318bb906de7d5a252414c1d3ea25322874e23e
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/src/exception.cpp b/src/exception.cpp
index f44cdaa..4a04dea 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -139,10 +139,12 @@
     return EINVAL;
 }
 
-UnpackPropertyError::UnpackPropertyError(std::string_view propertyName,
-                                         std::string_view reason) :
-    propertyName(propertyName),
-    reason(reason)
+UnpackPropertyError::UnpackPropertyError(std::string_view propertyNameIn,
+                                         std::string_view reasonIn) :
+    propertyName(propertyNameIn),
+    reason(reasonIn),
+    errWhatDetailed(std::string(errWhat) + " PropertyName: '" + propertyName +
+                    "', Reason: '" + reason + "'.")
 {}
 
 const char* UnpackPropertyError::name() const noexcept
@@ -157,7 +159,7 @@
 
 const char* UnpackPropertyError::what() const noexcept
 {
-    return errWhat;
+    return errWhatDetailed.c_str();
 }
 
 int UnpackPropertyError::get_errno() const noexcept