diff options
Diffstat (limited to 'zen/sys_error.h')
-rwxr-xr-x[-rw-r--r--] | zen/sys_error.h | 266 |
1 files changed, 105 insertions, 161 deletions
diff --git a/zen/sys_error.h b/zen/sys_error.h index 4798b959..a19409ab 100644..100755 --- a/zen/sys_error.h +++ b/zen/sys_error.h @@ -1,161 +1,105 @@ -// ***************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * -// ***************************************************************************** - -#ifndef SYS_ERROR_H_3284791347018951324534 -#define SYS_ERROR_H_3284791347018951324534 - -#include <string> -#include "utf.h" -#include "i18n.h" -#include "scope_guard.h" - -#ifdef ZEN_WIN - #include "win.h" //tame WinINet.h include - #include <WinINet.h> -#elif defined ZEN_LINUX || defined ZEN_MAC - #include <cstring> - #include <cerrno> -#endif - - -namespace zen -{ -//evaluate GetLastError()/errno and assemble specific error message -#ifdef ZEN_WIN - using ErrorCode = DWORD; -#elif defined ZEN_LINUX || defined ZEN_MAC - using ErrorCode = int; -#endif - -ErrorCode getLastError(); - -std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec); -std::wstring formatSystemError(const std::wstring& functionName, const std::wstring& errorCode, const std::wstring& errorMsg); - -//A low-level exception class giving (non-translated) detail information only - same conceptional level like "GetLastError()"! -class SysError -{ -public: - explicit SysError(const std::wstring& msg) : msg_(msg) {} - const std::wstring& toString() const { return msg_; } - -private: - std::wstring msg_; -}; - -#define DEFINE_NEW_SYS_ERROR(X) struct X : public SysError { X(const std::wstring& msg) : SysError(msg) {} }; - - - -#ifdef _MSC_VER -#define THROW_LAST_SYS_ERROR(functionName) \ - do \ - { \ - const ErrorCode ecInternal = getLastError(); \ - throw SysError(formatSystemError(functionName, ecInternal)); \ - \ - __pragma(warning(suppress: 4127)) /*"conditional expression is constant"*/ \ - } while (false) - -#else //same thing witout "__pragma": -#define THROW_LAST_SYS_ERROR(functionName) \ - do { const ErrorCode ecInternal = getLastError(); throw SysError(formatSystemError(functionName, ecInternal)); } while (false) -#endif - - - - - - -//######################## implementation ######################## -inline -ErrorCode getLastError() -{ -#ifdef ZEN_WIN - return ::GetLastError(); -#elif defined ZEN_LINUX || defined ZEN_MAC - return errno; //don't use "::", errno is a macro! -#endif -} - - -std::wstring formatSystemErrorRaw(long long) = delete; //intentional overload ambiguity to catch usage errors - -inline -std::wstring formatSystemErrorRaw(ErrorCode ec) //return empty string on error -{ - const ErrorCode currentError = getLastError(); //not necessarily == lastError - - std::wstring errorMsg; -#ifdef ZEN_WIN - ZEN_ON_SCOPE_EXIT(::SetLastError(currentError)); //this function must not change active system error variable! - - LPWSTR buffer = nullptr; - const DWORD rv = [&] - { - if (INTERNET_ERROR_BASE <= ec && ec <= INTERNET_ERROR_LAST) - return ::FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | - FORMAT_MESSAGE_MAX_WIDTH_MASK | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_ALLOCATE_BUFFER, ::GetModuleHandle(L"WinINet.dll"), ec, 0, reinterpret_cast<LPWSTR>(&buffer), 0, nullptr); - else - return ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_MAX_WIDTH_MASK | - FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, //_In_ DWORD dwFlags, - nullptr, //_In_opt_ LPCVOID lpSource, - ec, //_In_ DWORD dwMessageId, - 0, //_In_ DWORD dwLanguageId, - reinterpret_cast<LPWSTR>(&buffer), //_Out_ LPTSTR lpBuffer, - 0, //_In_ DWORD nSize, - nullptr); //_In_opt_ va_list *Arguments - }(); - if (rv != 0) - if (buffer) //"don't trust nobody" - { - ZEN_ON_SCOPE_EXIT(::LocalFree(buffer)); - errorMsg = buffer; - } - -#elif defined ZEN_LINUX || defined ZEN_MAC - ZEN_ON_SCOPE_EXIT(errno = currentError); - - errorMsg = utfCvrtTo<std::wstring>(::strerror(ec)); -#endif - trim(errorMsg); //Windows messages seem to end with a blank... - - return errorMsg; -} - - -std::wstring formatSystemError(const std::wstring& functionName, long long lastError) = delete; //intentional overload ambiguity to catch usage errors with HRESULT! - -inline -std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec) -{ - return formatSystemError(functionName, numberTo<std::wstring>(ec), formatSystemErrorRaw(ec)); -} - - -inline -std::wstring formatSystemError(const std::wstring& functionName, const std::wstring& errorCode, const std::wstring& errorMsg) -{ - std::wstring output = replaceCpy(_("Error Code %x:"), L"%x", errorCode); - - if (!errorMsg.empty()) - { - output += L" "; - output += errorMsg; - } - - output += L" (" + functionName + L")"; - - return output; -} - -} - -#endif //SYS_ERROR_H_3284791347018951324534 +// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#ifndef SYS_ERROR_H_3284791347018951324534
+#define SYS_ERROR_H_3284791347018951324534
+
+#include <string>
+#include "utf.h"
+#include "i18n.h"
+#include "scope_guard.h"
+
+ #include <cstring>
+ #include <cerrno>
+
+
+namespace zen
+{
+//evaluate GetLastError()/errno and assemble specific error message
+ using ErrorCode = int;
+
+ErrorCode getLastError();
+
+std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec);
+std::wstring formatSystemError(const std::wstring& functionName, const std::wstring& errorCode, const std::wstring& errorMsg);
+
+//A low-level exception class giving (non-translated) detail information only - same conceptional level like "GetLastError()"!
+class SysError
+{
+public:
+ explicit SysError(const std::wstring& msg) : msg_(msg) {}
+ const std::wstring& toString() const { return msg_; }
+
+private:
+ std::wstring msg_;
+};
+
+#define DEFINE_NEW_SYS_ERROR(X) struct X : public SysError { X(const std::wstring& msg) : SysError(msg) {} };
+
+
+
+#define THROW_LAST_SYS_ERROR(functionName) \
+ do { const ErrorCode ecInternal = getLastError(); throw SysError(formatSystemError(functionName, ecInternal)); } while (false)
+
+
+
+
+
+
+//######################## implementation ########################
+inline
+ErrorCode getLastError()
+{
+ return errno; //don't use "::", errno is a macro!
+}
+
+
+std::wstring formatSystemErrorRaw(long long) = delete; //intentional overload ambiguity to catch usage errors
+
+inline
+std::wstring formatSystemErrorRaw(ErrorCode ec) //return empty string on error
+{
+ const ErrorCode currentError = getLastError(); //not necessarily == lastError
+
+ std::wstring errorMsg;
+ ZEN_ON_SCOPE_EXIT(errno = currentError);
+
+ errorMsg = utfCvrtTo<std::wstring>(::strerror(ec));
+ trim(errorMsg); //Windows messages seem to end with a blank...
+
+ return errorMsg;
+}
+
+
+std::wstring formatSystemError(const std::wstring& functionName, long long lastError) = delete; //intentional overload ambiguity to catch usage errors with HRESULT!
+
+inline
+std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec)
+{
+ return formatSystemError(functionName, replaceCpy(_("Error Code %x"), L"%x", numberTo<std::wstring>(ec)), formatSystemErrorRaw(ec));
+}
+
+
+inline
+std::wstring formatSystemError(const std::wstring& functionName, const std::wstring& errorCode, const std::wstring& errorMsg)
+{
+ std::wstring output = errorCode + L":";
+
+ const std::wstring errorMsgFmt = trimCpy(errorMsg);
+ if (!errorMsgFmt.empty())
+ {
+ output += L" ";
+ output += errorMsgFmt;
+ }
+
+ output += L" [" + functionName + L"]";
+
+ return output;
+}
+
+}
+
+#endif //SYS_ERROR_H_3284791347018951324534
|