#pragma once #include #include #include #include const int _EL1_MULTIPLIER = 1'000'000 * -1; const int _EL2_MULTIPLIER = 1'000 * -1; enum HermesErrorL1 { E1_OK = 0 * _EL1_MULTIPLIER, E1_GENERIC = 1 * _EL1_MULTIPLIER, E1_RESOURCE = 2 * _EL1_MULTIPLIER, E1_ARGUMENT = 3 * _EL1_MULTIPLIER, E1_NETWORK = 4 * _EL1_MULTIPLIER, E1_SECURITY = 5 * _EL1_MULTIPLIER, }; enum HermesErrorL2 { E2_UNKNOWN = 0 * _EL2_MULTIPLIER, E2_CANCELLED = 1 * _EL2_MULTIPLIER, E2_ABORTED = 2 * _EL2_MULTIPLIER, E2_CRASH = 3 * _EL2_MULTIPLIER, E2_TIMEOUT = 4 * _EL2_MULTIPLIER, E2_OVERFLOW = 5 * _EL2_MULTIPLIER, E2_PRECONDITION_FAILURE = 6 * _EL2_MULTIPLIER, E2_NOT_READY = 7 * _EL2_MULTIPLIER, E2_ALREADY_EXIST = 8 * _EL2_MULTIPLIER, E2_INTERNAL_ERROR = 9 * _EL2_MULTIPLIER, E2_UNIMPLEMENTED = 10 * _EL2_MULTIPLIER, E2_NOT_SUPPORTED = 11 * _EL2_MULTIPLIER, E2_INVALID_ARGUMENT = 12 * _EL2_MULTIPLIER, E2_OUT_OF_RANGE = 13 * _EL2_MULTIPLIER, E2_NOT_FOUND = 14 * _EL2_MULTIPLIER, E2_UNAVAILABLE = 15 * _EL2_MULTIPLIER, E2_BUSY = 16 * _EL2_MULTIPLIER, E2_NOT_CONNECTED = 17 * _EL2_MULTIPLIER, E2_NO_RESPONSE = 18 * _EL2_MULTIPLIER, E2_REFUSED = 19 * _EL2_MULTIPLIER, E2_PERMISSION_DENIED = 20 * _EL2_MULTIPLIER, }; static const std::vector E1_ERR_MESSAGE { "OK", "GENERIC", "RESOURCE", "ARGUMENT", "NETWORK", "SECURITY", }; static const std::vector E2_ERR_MESSAGE { "", "CANCELLED", "ABORTED", "CRASH", "TIMEOUT", "OVERFLOW", "PRECONDITION_FAILURE", "NOT_READY", "ALREADY_EXIST", "INTERNAL_ERROR", "UNIMPLEMENTED", "NOT_SUPPORTED", "INVALID_ARGUMENT", "OUT_OF_RANGE", "NOT_FOUND", "UNAVAILABLE", "BUSY", "NOT_CONNECTED", "NO_RESPONSE", "REFUSED", "PERMISSION_DENIED", }; inline auto EC( HermesErrorL1 lev1, HermesErrorL2 lev2 = E2_UNKNOWN, int lev3 = 0 ) -> int { return lev1 + lev2 + (lev3 % _EL2_MULTIPLIER); }; inline std::string err_msg(int errorCode) { int e1 = errorCode / _EL1_MULTIPLIER; int e2 = errorCode % _EL1_MULTIPLIER / _EL2_MULTIPLIER; int e3 = errorCode % _EL2_MULTIPLIER; std::stringstream ss; ss << E1_ERR_MESSAGE[e1]; const auto& e2Str = E2_ERR_MESSAGE[e2]; if (e2Str.size() > 0) ss << " > " << e2Str; if (e3) ss << " > E3(" << e3 << ')'; return ss.str(); } #if defined(_WIN32) || defined(WIN32) #include inline std::unique_ptr winapiGetLastError(DWORD errCode) { static const int BUF_SIZE = 512; auto strBuf = std::make_unique(BUF_SIZE); int n = _snprintf_s(strBuf.get(), BUF_SIZE - 1, BUF_SIZE - 1, "(%d)", errCode); DWORD count = ::FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errCode, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), strBuf.get() + n, BUF_SIZE - n - 1, nullptr); if (count >= 2) strBuf[n + count - 2] = 0; return strBuf; } inline std::unique_ptr winapiGetLastError() { return winapiGetLastError(::GetLastError()); } #endif