X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Ferrorqueries.cpp;fp=src%2Ferrorqueries.cpp;h=55ba2c11508f5ccedfa6c1742bfdd9c7dbcb53df;hb=ef2bf51d04aaf01fa0cabdcaf905b23423067662;hp=0000000000000000000000000000000000000000;hpb=edc9b96a441194b571e8d55ec1603b5be0ea52eb;p=ric-plt%2Fsdl.git diff --git a/src/errorqueries.cpp b/src/errorqueries.cpp new file mode 100644 index 0000000..55ba2c1 --- /dev/null +++ b/src/errorqueries.cpp @@ -0,0 +1,120 @@ +/* + 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 +#include "config.h" +#include +#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(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(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(errorCode), getSharedDataLayerErrorCategory()}; + } +}