From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@dev.tarantool.org, kostja.osipov@gmail.com Subject: [Tarantool-patches] [PATCH 2/3] error: move errno into an error object Date: Tue, 5 Nov 2019 17:59:51 +0300 [thread overview] Message-ID: <848b353e29d6a692ce4e7015723cad31aa42b8dd.1572965692.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1572965692.git.v.shpilevoy@tarantool.org> The only error type having an errno as a part of it was SystemError (and its descendants SocketError, TimedOut, OOM, ...). That was used in logs (SystemError::log() method), and exposed to Lua (if type was SystemError, an error object had 'errno' field). But actually errno might be useful not only there. For example, box.info.replication exposes the latest error message of applier/relay as 'message' field of 'upstream/downstream' fields, lacking errno description. Before the patch it was impossible to obtain an errno code from C, because it was necessary to check whether an error has SystemError type, cast to SystemError class, and call SystemError::get_errno() method. Now errno is available as a part of struct error object (available from C), and is not 0 for system errors. Part of #4402 --- src/box/applier.cc | 2 +- src/lib/core/diag.c | 1 + src/lib/core/diag.h | 6 ++++++ src/lib/core/exception.cc | 22 ++++++++-------------- src/lib/core/exception.h | 5 ----- src/lua/error.lua | 10 ++++++++++ test/box/misc.result | 19 +++++++++++++++++++ test/box/misc.test.lua | 10 ++++++++++ 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/box/applier.cc b/src/box/applier.cc index a04d13564..a287f4219 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -181,7 +181,7 @@ applier_writer_f(va_list ap) * the master closed its end - we would only * spam the log - so exit immediately. */ - if (e->get_errno() == EPIPE) + if (e->syserror == EPIPE) break; /* * Do not exit, if there is a network error, diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index 248277e74..168f08225 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -44,6 +44,7 @@ error_create(struct error *e, e->log = log; e->type = type; e->refs = 0; + e->syserror = 0; if (file != NULL) { snprintf(e->file, sizeof(e->file), "%s", file); e->line = line; diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index fd3831e66..2f106d33f 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -72,6 +72,12 @@ struct error { error_f log; const struct type_info *type; int refs; + /** + * Errno at the moment of the error + * creation. If the error is not related + * to the standard library, then it is 0. + */ + int syserror; /** Line number. */ unsigned line; /* Source file name. */ diff --git a/src/lib/core/exception.cc b/src/lib/core/exception.cc index a6999af43..6e725a36c 100644 --- a/src/lib/core/exception.cc +++ b/src/lib/core/exception.cc @@ -129,27 +129,21 @@ Exception::log() const say_file_line(S_ERROR, file, line, errmsg, "%s", type->name); } -static const struct method_info systemerror_methods[] = { - make_method(&type_SystemError, "errno", &SystemError::get_errno), - METHODS_SENTINEL -}; - const struct type_info type_SystemError = - make_type("SystemError", &type_Exception, systemerror_methods); + make_type("SystemError", &type_Exception); SystemError::SystemError(const struct type_info *type, const char *file, unsigned line) - :Exception(type, file, line), - m_errno(errno) + :Exception(type, file, line) { - /* nothing */ + syserror = errno; } SystemError::SystemError(const char *file, unsigned line, const char *format, ...) - : Exception(&type_SystemError, file, line), - m_errno(errno) + : Exception(&type_SystemError, file, line) { + syserror = errno; va_list ap; va_start(ap, format); error_vformat_msg(this, format, ap); @@ -159,7 +153,7 @@ SystemError::SystemError(const char *file, unsigned line, void SystemError::log() const { - say_file_line(S_SYSERROR, file, line, strerror(m_errno), + say_file_line(S_SYSERROR, file, line, strerror(syserror), "SystemError %s", errmsg); } @@ -192,7 +186,7 @@ OutOfMemory::OutOfMemory(const char *file, unsigned line, const char *object) : SystemError(&type_OutOfMemory, file, line) { - m_errno = ENOMEM; + syserror = ENOMEM; error_format_msg(this, "Failed to allocate %u bytes in %s for %s", (unsigned) amount, allocator, object); } @@ -203,7 +197,7 @@ const struct type_info type_TimedOut = TimedOut::TimedOut(const char *file, unsigned line) : SystemError(&type_TimedOut, file, line) { - m_errno = ETIMEDOUT; + syserror = ETIMEDOUT; error_format_msg(this, "timed out"); } diff --git a/src/lib/core/exception.h b/src/lib/core/exception.h index a29281427..d6154eb32 100644 --- a/src/lib/core/exception.h +++ b/src/lib/core/exception.h @@ -86,17 +86,12 @@ class SystemError: public Exception { public: virtual void raise() { throw this; } - int get_errno() const { return m_errno; } - virtual void log() const; SystemError(const char *file, unsigned line, const char *format, ...); protected: SystemError(const struct type_info *type, const char *file, unsigned line); -protected: - /* system errno */ - int m_errno; }; extern const struct type_info type_SocketError; diff --git a/src/lua/error.lua b/src/lua/error.lua index 28fc0377d..575594273 100644 --- a/src/lua/error.lua +++ b/src/lua/error.lua @@ -17,6 +17,7 @@ struct error { error_f _log; const struct type_info *_type; int _refs; + int _syserror; /** Line number. */ unsigned _line; /* Source file name. */ @@ -86,10 +87,19 @@ local function error_trace(err) } end +local function error_errno(err) + local e = err._syserror + if e == 0 then + return nil + end + return e +end + local error_fields = { ["type"] = error_type; ["message"] = error_message; ["trace"] = error_trace; + ["errno"] = error_errno; } local function error_unpack(err) diff --git a/test/box/misc.result b/test/box/misc.result index b2930515b..d2a20307a 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -196,6 +196,25 @@ box.error.new() --- - error: 'Usage: box.error.new(code, args)' ... +-- +-- System errors expose errno as a field. +-- +_, err = require('fio').open('not_existing_file') +--- +... +type(err.errno) +--- +- number +... +-- Errors not related to the standard library do +-- not expose errno. +err = box.error.new(box.error.PROC_LUA, "errno") +--- +... +type(err.errno) +--- +- nil +... ---------------- -- # box.stat ---------------- diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index cc223b2ef..c3e992a48 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -59,6 +59,16 @@ e = box.error.new(box.error.CREATE_SPACE, "space", "error") e box.error.new() +-- +-- System errors expose errno as a field. +-- +_, err = require('fio').open('not_existing_file') +type(err.errno) +-- Errors not related to the standard library do +-- not expose errno. +err = box.error.new(box.error.PROC_LUA, "errno") +type(err.errno) + ---------------- -- # box.stat ---------------- -- 2.21.0 (Apple Git-122.2)
next prev parent reply other threads:[~2019-11-05 14:54 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-11-05 14:59 [Tarantool-patches] [PATCH 0/3] Replication status errno Vladislav Shpilevoy 2019-11-05 14:59 ` [Tarantool-patches] [PATCH 1/3] access: fix invalid error type for not found user Vladislav Shpilevoy 2019-11-05 18:15 ` Konstantin Osipov 2019-11-06 14:48 ` Vladislav Shpilevoy 2019-11-05 14:59 ` Vladislav Shpilevoy [this message] 2019-11-05 18:18 ` [Tarantool-patches] [PATCH 2/3] error: move errno into an error object Konstantin Osipov 2019-11-06 14:49 ` Vladislav Shpilevoy 2019-11-05 14:59 ` [Tarantool-patches] [PATCH 3/3] replication: show errno in replication info Vladislav Shpilevoy 2019-11-05 18:18 ` Konstantin Osipov 2019-11-05 18:13 ` [Tarantool-patches] [PATCH 0/3] Replication status errno Konstantin Osipov 2019-11-21 17:38 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=848b353e29d6a692ce4e7015723cad31aa42b8dd.1572965692.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja.osipov@gmail.com \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 2/3] error: move errno into an error object' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox