summaryrefslogtreecommitdiff
path: root/zen/sys_error.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/sys_error.cpp')
-rw-r--r--zen/sys_error.cpp122
1 files changed, 106 insertions, 16 deletions
diff --git a/zen/sys_error.cpp b/zen/sys_error.cpp
index f9747d45..fa7352f0 100644
--- a/zen/sys_error.cpp
+++ b/zen/sys_error.cpp
@@ -5,24 +5,11 @@
// *****************************************************************************
#include "sys_error.h"
- #include <cstring>
+ #include <gio/gio.h>
using namespace zen;
-
-
-std::wstring zen::getSystemErrorDescription(ErrorCode ec) //return empty string on error
-{
- const ErrorCode currentError = getLastError(); //not necessarily == ec
- ZEN_ON_SCOPE_EXIT(errno = currentError);
-
- std::wstring errorMsg;
- errorMsg = utfTo<std::wstring>(::strerror(ec));
- return trimCpy(errorMsg); //Windows messages seem to end with a space...
-}
-
-
namespace
{
std::wstring formatSystemErrorCode(ErrorCode ec)
@@ -168,6 +155,109 @@ std::wstring formatSystemErrorCode(ErrorCode ec)
}
+std::wstring zen::formatGlibError(const std::string& functionName, GError* error)
+{
+ if (!error)
+ return formatSystemError(functionName, L"", _("Error description not available.") + L" null GError");
+
+ if (error->domain == G_FILE_ERROR) //"values corresponding to errno codes"
+ return formatSystemError(functionName, error->code);
+
+ std::wstring errorCode;
+ if (error->domain == G_IO_ERROR)
+ errorCode = [&]() -> std::wstring
+ {
+ switch (error->code) //GIOErrorEnum: https://gitlab.gnome.org/GNOME/glib/-/blob/master/gio/gioenums.h#L530
+ {
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_FAILED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_FOUND);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_EXISTS);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_IS_DIRECTORY);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_DIRECTORY);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_EMPTY);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_REGULAR_FILE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_SYMBOLIC_LINK);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_MOUNTABLE_FILE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_FILENAME_TOO_LONG);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_INVALID_FILENAME);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_TOO_MANY_LINKS);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NO_SPACE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_INVALID_ARGUMENT);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PERMISSION_DENIED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_SUPPORTED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_MOUNTED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_ALREADY_MOUNTED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_CLOSED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_CANCELLED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PENDING);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_READ_ONLY);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_CANT_CREATE_BACKUP);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_WRONG_ETAG);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_TIMED_OUT);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_WOULD_RECURSE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_BUSY);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_WOULD_BLOCK);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_HOST_NOT_FOUND);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_WOULD_MERGE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_FAILED_HANDLED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_TOO_MANY_OPEN_FILES);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_INITIALIZED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_ADDRESS_IN_USE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PARTIAL_INPUT);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_INVALID_DATA);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_DBUS_ERROR);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_HOST_UNREACHABLE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NETWORK_UNREACHABLE);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_CONNECTION_REFUSED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PROXY_FAILED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PROXY_AUTH_FAILED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PROXY_NEED_AUTH);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_PROXY_NOT_ALLOWED);
+#ifndef GLIB_CHECK_VERSION //e.g Debian 8 (GLib 2.42) CentOS 7 (GLib 2.56)
+#error Where is GLib?
+#endif
+#if GLIB_CHECK_VERSION(2, 44, 0)
+ static_assert(G_IO_ERROR_BROKEN_PIPE == G_IO_ERROR_CONNECTION_CLOSED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_CONNECTION_CLOSED);
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_NOT_CONNECTED);
+#endif
+#if GLIB_CHECK_VERSION(2, 48, 0)
+ ZEN_CHECK_CASE_FOR_CONSTANT(G_IO_ERROR_MESSAGE_TOO_LARGE);
+#endif
+ default:
+ return replaceCpy<std::wstring>(L"GIO error %x", L"%x", numberTo<std::wstring>(error->code));
+ }
+ }();
+ else
+ {
+ //g-file-error-quark => g-file-error
+ //g-io-error-quark => g-io-error
+ std::wstring domain = utfTo<std::wstring>(::g_quark_to_string(error->domain)); //e.g. "g-io-error-quark"
+ if (endsWith(domain, L"-quark"))
+ domain = beforeLast(domain, L"-", IfNotFoundReturn::none);
+
+ errorCode = domain + L' ' + numberTo<std::wstring>(error->code); //e.g. "g-io-error 15"
+ }
+
+ const std::wstring errorMsg = utfTo<std::wstring>(error->message); //e.g. "Unable to find or create trash directory for file.txt"
+
+ return formatSystemError(functionName, errorCode, errorMsg);
+}
+
+
+
+std::wstring zen::getSystemErrorDescription(ErrorCode ec) //return empty string on error
+{
+ const ErrorCode currentError = getLastError(); //not necessarily == ec
+ ZEN_ON_SCOPE_EXIT(errno = currentError);
+
+ std::wstring errorMsg;
+ errorMsg = utfTo<std::wstring>(::g_strerror(ec)); //... vs strerror(): "marginally improves thread safety, and marginally improves consistency"
+
+ return trimCpy(errorMsg); //Windows messages seem to end with a space...
+}
+
+
std::wstring zen::formatSystemError(const std::string& functionName, ErrorCode ec)
{
return formatSystemError(functionName, formatSystemErrorCode(ec), getSystemErrorDescription(ec));
@@ -176,10 +266,10 @@ std::wstring zen::formatSystemError(const std::string& functionName, ErrorCode e
std::wstring zen::formatSystemError(const std::string& functionName, const std::wstring& errorCode, const std::wstring& errorMsg)
{
- std::wstring output = errorCode;
+ std::wstring output = trimCpy(errorCode);
const std::wstring errorMsgFmt = trimCpy(errorMsg);
- if (!errorCode.empty() && !errorMsgFmt.empty())
+ if (!output.empty() && !errorMsgFmt.empty())
output += L": ";
output += errorMsgFmt;
bgstack15