--- /dev/null
+/*
+ Copyright (c) 2018-2019 Nokia.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <sstream>
+#include "config.h"
+#include <sdl/errorqueries.hpp>
+#include "private/createlogger.hpp"
+#include "private/error.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+ class SharedDataLayerErrorCategory : public std::error_category
+ {
+ public:
+ SharedDataLayerErrorCategory() = default;
+ const char* name() const noexcept override;
+ std::string message(int condition) const override;
+ bool equivalent(const std::error_code& ec, int condition) const noexcept override;
+ };
+
+ const char* SharedDataLayerErrorCategory::name() const noexcept
+ {
+ return "shareddatalayer-errorcodes";
+ }
+
+ std::string SharedDataLayerErrorCategory::message(int condition) const
+ {
+ switch (static_cast<shareddatalayer::Error>(condition))
+ {
+ case shareddatalayer::Error::SUCCESS:
+ return std::error_code().message();
+ case shareddatalayer::Error::NOT_CONNECTED:
+ return "shareddatalayer not connected to backend data storage";
+ case shareddatalayer::Error::OPERATION_INTERRUPTED:
+ return "shareddatalayer sent the request to backend data storage but did not receive reply";
+ case shareddatalayer::Error::BACKEND_FAILURE:
+ return "backend data storage failed to process the request";
+ case shareddatalayer::Error::REJECTED_BY_BACKEND:
+ return "backend data storage rejected the request";
+ case shareddatalayer::Error::REJECTED_BY_SDL:
+ return "SDL rejected the request";
+ default:
+ return "description missing for SharedDataLayerErrorCategory error: " + std::to_string(condition);
+ }
+ }
+
+ const std::error_category& getSharedDataLayerErrorCategory() noexcept
+ {
+ static const SharedDataLayerErrorCategory theSharedDataLayerErrorCategory;
+ return theSharedDataLayerErrorCategory;
+ }
+
+
+ bool SharedDataLayerErrorCategory::equivalent(const std::error_code& ec, int condition) const noexcept
+ {
+ /* Reasoning for possibly not self-evident mappings:
+ - InternalError::BACKEND_NOT_READY is mapped to shareddatalayer::Error::NOT_CONNECTED
+ even though we are connected to backend in that situation. Client handling for InternalError::BACKEND_NOT_READY
+ situation is identical than handling for other shareddatalayer::Error::NOT_CONNECTED client error cases.
+ To have minimal amount of client error codes we map it to that.
+ - InternalError::SDL_ERROR_CODE_LOGIC_ERROR is mapped to shareddatalayer::Error::BACKEND_FAILURE.
+ That internal failure should never happen. If it does happen, we cannot know here which kind of error
+ has really happened. Thus we map to the most severe client error code (other places will write logs about this).
+ */
+ switch (static_cast<shareddatalayer::Error>(condition))
+ {
+ case shareddatalayer::Error::SUCCESS:
+ return ec == InternalError::SUCCESS ||
+ ec == std::error_code();
+ case shareddatalayer::Error::NOT_CONNECTED:
+ return ec == InternalError::SDL_NOT_CONNECTED_TO_BACKEND ||
+ ec == InternalError::BACKEND_NOT_READY ||
+ ec == InternalError::SDL_NOT_READY;
+ case shareddatalayer::Error::OPERATION_INTERRUPTED:
+ return ec == InternalError::BACKEND_CONNECTION_LOST;
+ case shareddatalayer::Error::BACKEND_FAILURE:
+ return ec == InternalError::BACKEND_ERROR ||
+ ec == InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+ case shareddatalayer::Error::REJECTED_BY_BACKEND:
+ return ec == InternalError::BACKEND_REJECTED_REQUEST;
+ case shareddatalayer::Error::REJECTED_BY_SDL:
+ return ec == InternalError::SDL_RECEIVED_INVALID_PARAMETER;
+ default:
+ /* Since clients can compare shareddatalayer::Error conditions against any std::error_code based ec, this error log
+ * can occur without fault in SDL implementation. If error log appears:
+ * - First check is the problematic ec set in SDL implementation
+ * - If yes, do needed updates to SDL (update error mappings for given ec or change SDL to set some error_code)
+ * - If no, ask client to check why they are comparing non-SDL originated error_code against shareddatalayer::Error
+ */
+ std::ostringstream msg;
+ msg << "SharedDataLayerErrorCategory::equivalent no mapping for error: " << ec.category().name()
+ << ec.value();
+ logErrorOnce(msg.str());
+ return false;
+ }
+ }
+}
+
+namespace shareddatalayer
+{
+ std::error_condition make_error_condition(shareddatalayer::Error errorCode)
+ {
+ return {static_cast<int>(errorCode), getSharedDataLayerErrorCategory()};
+ }
+}