331 lines
9.9 KiB
C++
Executable File
331 lines
9.9 KiB
C++
Executable File
#pragma once
|
|
|
|
#include <string_view>
|
|
#include <tl/expected.hpp>
|
|
|
|
#include <rublon/non_owning_ptr.hpp>
|
|
#include <rublon/stdlib.hpp>
|
|
#include <rublon/utils.hpp>
|
|
|
|
namespace rublon {
|
|
|
|
class ConfigurationError {
|
|
public:
|
|
enum class ErrorClass { //
|
|
RequiredValueNotFound,
|
|
RequiredValueEmpty,
|
|
BadFailMode,
|
|
BadInput,
|
|
BadConfiguration,
|
|
Empty
|
|
};
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"RequiredValueNotFound",
|
|
"RequiredValueEmpty",
|
|
"BadFailMode",
|
|
"BadInput",
|
|
"BadConfiguration",
|
|
"Empty");
|
|
constexpr static auto prettyName = "Configurtion Error";
|
|
|
|
constexpr ConfigurationError(ErrorClass e = ErrorClass::RequiredValueNotFound) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class ConnectionError {
|
|
public:
|
|
enum ErrorClass { //
|
|
Timeout,
|
|
HttpError,
|
|
ClientError
|
|
};
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"Timeout",
|
|
"Error",
|
|
"Client Error");
|
|
constexpr static auto prettyName = "Connection Error";
|
|
|
|
constexpr ConnectionError() : errorClass{Timeout}, httpCode(200) {}
|
|
constexpr ConnectionError(ErrorClass e, long httpCode) : errorClass{e}, httpCode(httpCode) {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
long httpCode;
|
|
};
|
|
|
|
class CoreHandlerError {
|
|
public:
|
|
enum ErrorClass {
|
|
BadSigature,
|
|
RublonCoreException,
|
|
BrokenData,
|
|
APIException, // code: 10
|
|
TransactionException,
|
|
TransactionIdExpiredException, // code: 11
|
|
TransactionAccessTokenExpiredException, // code: 11
|
|
TooManyRequestsException
|
|
};
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"BadSigature",
|
|
"RublonCoreException",
|
|
"BrokenData",
|
|
"APIException",
|
|
"TransactionException",
|
|
"TransactionIdExpiredException",
|
|
"TransactionAccessTokenExpiredException",
|
|
"TooManyRequestsException");
|
|
constexpr static auto prettyName = "Core Handler Error";
|
|
|
|
// APIException -> code: 10
|
|
// TransactionException -> code: 11
|
|
|
|
CoreHandlerError(ErrorClass e = BadSigature) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
static std::optional< CoreHandlerError > fromString(std::string_view name) {
|
|
for(std::size_t i{}; i < errorClassPrettyName.size(); i++) {
|
|
if(errorClassPrettyName.at(i) == name) {
|
|
return std::make_optional(CoreHandlerError{static_cast< ErrorClass >(i)});
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class MethodError {
|
|
public:
|
|
enum ErrorClass { BadMethod, BadUserInput, NoMethodAvailable };
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >("BadMethod", "BadUserInput", "NoMethodAvailable");
|
|
constexpr static auto prettyName = "Method Error";
|
|
|
|
constexpr MethodError(ErrorClass e = BadMethod) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class WerificationError {
|
|
public:
|
|
enum ErrorClass {
|
|
BadInput, // User input has incorrect characters or length
|
|
SecurityKeyException, // code: 16
|
|
PasscodeException, // code: 18
|
|
SendPushException, // code: 21 | this code really should not be here as rest of the codes are strictly for passcode verification
|
|
TooManyRequestsException // code: 101
|
|
};
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"BadInput",
|
|
"SecurityKeyException",
|
|
"PasscodeException",
|
|
"SendPushException",
|
|
"TooManyRequestsException");
|
|
constexpr static inline auto prettyName = "Werification Error";
|
|
|
|
constexpr WerificationError(ErrorClass e = PasscodeException) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
static std::optional< WerificationError > fromString(std::string_view name) {
|
|
for(std::size_t i{}; i < errorClassPrettyName.size(); i++) {
|
|
if(errorClassPrettyName.at(i) == name) {
|
|
return std::make_optional(WerificationError{static_cast< ErrorClass >(i)});
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class RublonAuthenticationInterrupt {
|
|
public:
|
|
// UserPending -> user has no methods configured
|
|
enum ErrorClass { //
|
|
UserBaypass,
|
|
UserDenied,
|
|
UserPending,
|
|
UserWaiting,
|
|
UserNotFound
|
|
};
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"UserBypassedException",
|
|
"UserDenied",
|
|
"UserPending",
|
|
"UserWaiting",
|
|
"UserNotFoundException");
|
|
constexpr static auto prettyName = "Rublon Authentication Interrupt";
|
|
|
|
RublonAuthenticationInterrupt(ErrorClass e = UserBaypass) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
static std::optional< RublonAuthenticationInterrupt > fromString(std::string_view name) {
|
|
for(std::size_t i{}; i < errorClassPrettyName.size(); i++) {
|
|
if(errorClassPrettyName.at(i) == name) {
|
|
return std::make_optional(RublonAuthenticationInterrupt{static_cast< ErrorClass >(i)});
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class RublonCheckApplicationException {
|
|
public:
|
|
enum ErrorClass {
|
|
MissingFieldException,
|
|
ApplicationNotFoundException,
|
|
InvalidSignatureException, // code: 9
|
|
UnsupportedVersionException
|
|
};
|
|
|
|
constexpr static auto errorClassPrettyName = make_array< std::string_view >( //
|
|
"MissingFieldException",
|
|
"ApplicationNotFoundException",
|
|
"InvalidSignatureException",
|
|
"UnsupportedVersionException");
|
|
constexpr static auto prettyName = "Rublon Check Application Interrupt";
|
|
|
|
RublonCheckApplicationException(ErrorClass e = ApplicationNotFoundException) : errorClass{e} {}
|
|
|
|
constexpr const char * what() const {
|
|
return errorClassPrettyName[static_cast< int >(errorClass)].data();
|
|
}
|
|
|
|
static std::optional< RublonCheckApplicationException > fromString(std::string_view name) {
|
|
for(std::size_t i{}; i < errorClassPrettyName.size(); i++) {
|
|
if(errorClassPrettyName.at(i) == name) {
|
|
return std::make_optional(RublonCheckApplicationException{static_cast< ErrorClass >(i)});
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
ErrorClass errorClass;
|
|
};
|
|
|
|
class Error {
|
|
using Error_t = std::variant< ConfigurationError,
|
|
CoreHandlerError,
|
|
ConnectionError,
|
|
WerificationError,
|
|
MethodError,
|
|
RublonAuthenticationInterrupt,
|
|
RublonCheckApplicationException >;
|
|
Error_t _error;
|
|
|
|
public:
|
|
enum Category {
|
|
k_ConfigurationError,
|
|
k_CoreHandlerError,
|
|
k_ConnectionError,
|
|
k_WerificationError,
|
|
k_MethodError,
|
|
k_RublonAuthenticationInterrupt,
|
|
k_RublonCheckApplication
|
|
};
|
|
|
|
Error() = default;
|
|
|
|
Error(ConfigurationError error) : _error{error} {}
|
|
Error(CoreHandlerError error) : _error{error} {}
|
|
Error(ConnectionError error) : _error{error} {}
|
|
Error(MethodError error) : _error{error} {}
|
|
Error(WerificationError error) : _error{error} {}
|
|
Error(RublonAuthenticationInterrupt error) : _error{error} {}
|
|
Error(RublonCheckApplicationException error) : _error{error} {}
|
|
|
|
Error(const Error &) = default;
|
|
Error(Error &&) = default;
|
|
|
|
Error & operator=(const Error &) = default;
|
|
Error & operator=(Error &&) = default;
|
|
|
|
public:
|
|
constexpr bool coreError() const {
|
|
return _error.index() == 1;
|
|
}
|
|
|
|
constexpr bool sockerError() const {
|
|
return _error.index() == 2;
|
|
}
|
|
|
|
constexpr Category category() const noexcept {
|
|
return static_cast< Category >(_error.index());
|
|
}
|
|
|
|
constexpr const char * categoryName() const noexcept {
|
|
return std::visit([](const auto & e) { return e.what(); }, _error);
|
|
}
|
|
|
|
constexpr int errorClass() const noexcept {
|
|
return std::visit([](const auto & e) { return static_cast< int >(e.errorClass); }, _error);
|
|
}
|
|
|
|
constexpr const char * errorClassName() const noexcept {
|
|
return std::visit([](const auto & e) { return e.prettyName; }, _error);
|
|
}
|
|
|
|
template < typename E >
|
|
constexpr bool is() const {
|
|
return category() == Error{E{}}.category();
|
|
}
|
|
|
|
template < typename E >
|
|
constexpr bool is(typename E::ErrorClass errorClass) const {
|
|
return is< E >() && hasSameErrorClassAs(errorClass);
|
|
}
|
|
|
|
template < typename E >
|
|
constexpr bool isSameCategoryAs(const E & e) const {
|
|
return category() == Error{e}.category();
|
|
}
|
|
|
|
constexpr bool hasClass(int _class) const {
|
|
return errorClass() == _class;
|
|
}
|
|
|
|
template < typename E >
|
|
constexpr bool hasSameErrorClassAs(E e) const {
|
|
assert(isSameCategoryAs(e));
|
|
return errorClass() == Error{e}.errorClass();
|
|
}
|
|
|
|
template < typename E >
|
|
constexpr const E & get() const {
|
|
return std::get< E >(_error);
|
|
}
|
|
};
|
|
|
|
constexpr bool operator==(const Error & e, const ConnectionError & socket) {
|
|
return e.sockerError() && e.errorClass() == socket.errorClass;
|
|
}
|
|
|
|
template < typename T >
|
|
constexpr bool operator==(const Error & lhs, const T & rhs) {
|
|
return lhs.isSameCategoryAs(rhs) && lhs.hasSameErrorClassAs(rhs);
|
|
}
|
|
|
|
} // namespace rublon
|