From: Vladislav Shpilevoy via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org Subject: [Tarantool-patches] [PATCH v2 05/11] error: use error_payload to store optional members Date: Fri, 12 Nov 2021 00:54:26 +0100 [thread overview] Message-ID: <e69a76c15ef0606fa08241f392842741d8ed82ca.1636674803.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1636674803.git.v.shpilevoy@tarantool.org> error_payload is a part of struct error now. All the fields stored in C++ classes on top of struct error are moved into the payload. Part of #5568 --- src/box/error.cc | 11 +++--- src/box/error.h | 34 ++++------------- src/lib/core/diag.c | 2 + src/lib/core/diag.h | 82 +++++++++++++++++++++++++++++++++++++++++ src/lua/error.lua | 12 ++++++ test/box/error.result | 4 +- test/box/error.test.lua | 2 +- 7 files changed, 112 insertions(+), 35 deletions(-) diff --git a/src/box/error.cc b/src/box/error.cc index bc0d46601..34e807eb3 100644 --- a/src/box/error.cc +++ b/src/box/error.cc @@ -305,9 +305,9 @@ AccessDeniedError::AccessDeniedError(const char *file, unsigned int line, */ if (run_trigers) trigger_run(&on_access_denied, (void *) &ctx); - m_object_type = strdup(object_type); - m_access_type = strdup(access_type); - m_object_name = strdup(object_name); + error_set_str(this, "object_type", object_type); + error_set_str(this, "object_name", object_name); + error_set_str(this, "access_type", access_type); } struct error * @@ -337,15 +337,14 @@ CustomError::CustomError(const char *file, unsigned int line, const char *custom_type, uint32_t errcode) :ClientError(&type_CustomError, file, line, errcode) { - strncpy(m_custom_type, custom_type, sizeof(m_custom_type) - 1); - m_custom_type[sizeof(m_custom_type) - 1] = '\0'; + error_set_str(this, "custom_type", custom_type); } void CustomError::log() const { say_file_line(S_ERROR, file, line, errmsg, - "Custom type %s", m_custom_type); + "Custom type %s", custom_type()); } struct error * diff --git a/src/box/error.h b/src/box/error.h index 30ab36a97..cc37412d7 100644 --- a/src/box/error.h +++ b/src/box/error.h @@ -243,38 +243,23 @@ public: const char *object_name, const char *user_name, bool run_trigers = true); - ~AccessDeniedError() - { - free(m_object_name); - free(m_object_type); - free(m_access_type); - } - const char * - object_type() + object_type() const { - return m_object_type; + return error_get_str(this, "object_type"); } const char * - object_name() + object_name() const { - return m_object_name?:"(nil)"; + return error_get_str(this, "object_name"); } const char * - access_type() + access_type() const { - return m_access_type; + return error_get_str(this, "access_type"); } - -private: - /** Type of object the required access was denied to */ - char *m_object_type; - /** Name of object the required access was denied to */ - char *m_object_name; - /** Type of declined access */ - char *m_access_type; }; /** @@ -319,13 +304,10 @@ public: virtual void log() const; const char* - custom_type() + custom_type() const { - return m_custom_type; + return error_get_str(this, "custom_type"); } -private: - /** Custom type name. */ - char m_custom_type[64]; }; #endif /* defined(__cplusplus) */ diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index b557ca667..217c3ae7e 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -53,6 +53,7 @@ error_unref(struct error *e) to_delete->cause->effect = NULL; to_delete->cause = NULL; } + error_payload_destroy(&to_delete->payload); to_delete->destroy(to_delete); if (cause == NULL) return; @@ -117,6 +118,7 @@ error_create(struct error *e, e->refs = 0; e->saved_errno = 0; e->code = 0; + error_payload_create(&e->payload); 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 30b8d2f5d..c3e7470e8 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -36,6 +36,8 @@ #include <stdint.h> #include <stdbool.h> #include <assert.h> + +#include "error_payload.h" #include "say.h" #if defined(__cplusplus) @@ -89,6 +91,8 @@ struct error { int saved_errno; /** Error code. Shortest possible description of error's reason. */ int code; + /** Key-value storage with error's dynamic fields. */ + struct error_payload payload; /** Line number. */ unsigned line; /* Source file name. */ @@ -120,6 +124,84 @@ error_ref(struct error *e); void error_unref(struct error *e); +static inline const char * +error_get_str(const struct error *e, const char *name) +{ + return error_payload_get_str(&e->payload, name); +} + +static inline void +error_set_str(struct error *e, const char *name, const char *value) +{ + error_payload_set_str(&e->payload, name, value); +} + +static inline bool +error_get_uint(const struct error *e, const char *name, uint64_t *value) +{ + return error_payload_get_uint(&e->payload, name, value); +} + +static inline void +error_set_uint(struct error *e, const char *name, uint64_t value) +{ + error_payload_set_uint(&e->payload, name, value); +} + +static inline bool +error_get_int(const struct error *e, const char *name, int64_t *value) +{ + return error_payload_get_int(&e->payload, name, value); +} + +static inline void +error_set_int(struct error *e, const char *name, int64_t value) +{ + error_payload_set_int(&e->payload, name, value); +} + +static inline bool +error_get_double(const struct error *e, const char *name, double *value) +{ + return error_payload_get_double(&e->payload, name, value); +} + +static inline void +error_set_double(struct error *e, const char *name, double value) +{ + error_payload_set_double(&e->payload, name, value); +} + +static inline bool +error_get_bool(const struct error *e, const char *name, bool *value) +{ + return error_payload_get_bool(&e->payload, name, value); +} + +static inline void +error_set_bool(struct error *e, const char *name, bool value) +{ + error_payload_set_bool(&e->payload, name, value); +} + +static inline bool +error_get_uuid(const struct error *e, const char *name, struct tt_uuid *value) +{ + return error_payload_get_uuid(&e->payload, name, value); +} + +static inline void +error_set_uuid(struct error *e, const char *name, const struct tt_uuid *value) +{ + error_payload_set_uuid(&e->payload, name, value); +} + +static inline void +error_clear_field(struct error *e, const char *name) +{ + error_payload_clear(&e->payload, name); +} + /** * Unlink error from its effect. For instance: * e1 -> e2 -> e3 -> e4 (e1:set_prev(e2); e2:set_prev(e3) ...) diff --git a/src/lua/error.lua b/src/lua/error.lua index 9fb227df4..fb48a9b18 100644 --- a/src/lua/error.lua +++ b/src/lua/error.lua @@ -11,6 +11,17 @@ enum { typedef void (*error_f)(struct error *e); +struct error_field { + char *_data; + uint32_t _size; + char _name[1]; +}; + +struct error_payload { + int _count; + struct error_field **_fields; +}; + struct error { error_f _destroy; error_f _raise; @@ -19,6 +30,7 @@ struct error { int64_t _refs; int _saved_errno; int code; + struct error_payload _payload; /** Line number. */ unsigned _line; /* Source file name. */ diff --git a/test/box/error.result b/test/box/error.result index 19ea53873..7583306a6 100644 --- a/test/box/error.result +++ b/test/box/error.result @@ -899,13 +899,13 @@ e:unpack() | - file: '[string "e = box.error.new({type = ''TestType''}) "]' | line: 1 | ... --- Try too long type name. +-- Try long type name. e = box.error.new({type = string.rep('a', 128)}) | --- | ... #e.type | --- - | - 63 + | - 128 | ... -- gh-4887: accessing 'prev' member also refs it so that after diff --git a/test/box/error.test.lua b/test/box/error.test.lua index ed95d1d41..068212d96 100644 --- a/test/box/error.test.lua +++ b/test/box/error.test.lua @@ -241,7 +241,7 @@ e:unpack() -- Try to omit message. e = box.error.new({type = 'TestType'}) e:unpack() --- Try too long type name. +-- Try long type name. e = box.error.new({type = string.rep('a', 128)}) #e.type -- 2.24.3 (Apple Git-128)
next prev parent reply other threads:[~2021-11-11 23:58 UTC|newest] Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-11-11 23:54 [Tarantool-patches] [PATCH v2 00/11] ER_READONLY reason Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 01/11] diag: return created error from diag_set() Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 10/11] box: enrich ER_READONLY with new details Vladislav Shpilevoy via Tarantool-patches 2021-11-12 7:30 ` Serge Petrenko via Tarantool-patches 2021-11-12 23:24 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-15 6:51 ` Serge Petrenko via Tarantool-patches 2021-11-15 21:56 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-16 9:53 ` Serge Petrenko via Tarantool-patches 2021-11-16 22:08 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 11/11] error: report ER_READONLY reason in message Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 02/11] uuid: move into libcore Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 03/11] error: introduce error_payload Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 04/11] error: move code to struct error from ClientError Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` Vladislav Shpilevoy via Tarantool-patches [this message] 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 06/11] error: use error_payload in MessagePack codecs Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 07/11] error: use error_payload in Lua Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 08/11] luatest: copy config in cluster:build_server() Vladislav Shpilevoy via Tarantool-patches 2021-11-11 23:54 ` [Tarantool-patches] [PATCH v2 09/11] luatest: add new helpers for 'server' object Vladislav Shpilevoy via Tarantool-patches 2021-11-12 23:25 ` [Tarantool-patches] [PATCH v2 12/11] error: introduce box.info.ro_reason Vladislav Shpilevoy via Tarantool-patches 2021-11-15 6:53 ` Serge Petrenko via Tarantool-patches 2021-11-16 22:08 ` [Tarantool-patches] [PATCH v2 00/11] ER_READONLY reason Vladislav Shpilevoy via Tarantool-patches
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=e69a76c15ef0606fa08241f392842741d8ed82ca.1636674803.git.v.shpilevoy@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=sergepetrenko@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 05/11] error: use error_payload to store optional members' \ /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