From: Vladislav Shpilevoy via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: tarantool-patches@dev.tarantool.org, sergepetrenko@tarantool.org, vdavydov@tarantool.org Subject: [Tarantool-patches] [PATCH 5/9] error: use error_payload in MessagePack codecs Date: Sat, 6 Nov 2021 00:56:36 +0100 [thread overview] Message-ID: <7adc72ff7c2de0a662e2591234eade251fb83f27.1636156453.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1636156453.git.v.shpilevoy@tarantool.org> Before this patch mp_error API could only encode and decode hardcoded fields from the C++ classes inheriting struct error. The fields are gone from the classes in a previous patch - moved into error_payload. Now to be able to support arbitrary fields in the payload the MessagePack encoding/decoding must use its content instead of hardcoded fields depending on error type. Part of #5568 --- src/box/error.cc | 7 -- src/box/error.h | 28 +++++- src/box/mp_error.cc | 194 +++++++++++--------------------------- src/lib/core/diag.c | 17 ++-- src/lib/core/diag.h | 9 ++ src/lib/core/exception.h | 66 +++++++++++++ test/unit/mp_error.cc | 76 ++++++++++++++- test/unit/mp_error.result | 27 +++++- 8 files changed, 262 insertions(+), 162 deletions(-) diff --git a/src/box/error.cc b/src/box/error.cc index 629ec703f..be3b3b6f5 100644 --- a/src/box/error.cc +++ b/src/box/error.cc @@ -256,13 +256,6 @@ XlogGapError::XlogGapError(const char *file, unsigned line, (long long) vclock_sum(to), s_to ? s_to : ""); } -XlogGapError::XlogGapError(const char *file, unsigned line, - const char *msg) - : XlogError(&type_XlogGapError, file, line) -{ - error_format_msg(this, "%s", msg); -} - struct error * BuildXlogGapError(const char *file, unsigned line, const struct vclock *from, const struct vclock *to) diff --git a/src/box/error.h b/src/box/error.h index 43faaea70..c2ccf48bb 100644 --- a/src/box/error.h +++ b/src/box/error.h @@ -213,6 +213,11 @@ public: ClientError(const char *file, unsigned line, uint32_t errcode, ...); + ClientError() + :Exception(&type_ClientError, NULL, 0) + { + } + static uint32_t get_errcode(const struct error *e); protected: ClientError(const type_info *type, const char *file, unsigned line, @@ -243,6 +248,11 @@ public: const char *object_name, const char *user_name, bool run_trigers = true); + AccessDeniedError() + :ClientError(&type_AccessDeniedError, NULL, 0, 0) + { + } + const char * object_type() const { @@ -276,6 +286,12 @@ struct XlogError: public Exception { error_vformat_msg(this, format, ap); } + + XlogError() + :Exception(&type_XlogError, NULL, 0) + { + } + XlogError(const struct type_info *type, const char *file, unsigned line) :Exception(type, file, line) @@ -289,8 +305,11 @@ struct XlogGapError: public XlogError { XlogGapError(const char *file, unsigned line, const struct vclock *from, const struct vclock *to); - XlogGapError(const char *file, unsigned line, - const char *msg); + + XlogGapError() + :XlogError(&type_XlogGapError, NULL, 0) + { + } virtual void raise() { throw this; } }; @@ -301,6 +320,11 @@ public: CustomError(const char *file, unsigned int line, const char *custom_type, uint32_t errcode); + CustomError() + :ClientError(&type_CustomError, NULL, 0, 0) + { + } + virtual void log() const; const char* diff --git a/src/box/mp_error.cc b/src/box/mp_error.cc index 35c770400..fba562a84 100644 --- a/src/box/mp_error.cc +++ b/src/box/mp_error.cc @@ -118,35 +118,31 @@ struct mp_error { const char *type; const char *file; const char *message; - const char *custom_type; - const char *ad_object_type; - const char *ad_object_name; - const char *ad_access_type; + struct error_payload payload; }; static void mp_error_create(struct mp_error *mp_error) { memset(mp_error, 0, sizeof(*mp_error)); + error_payload_create(&mp_error->payload); +} + +static void +mp_error_destroy(struct mp_error *mp_error) +{ + error_payload_destroy(&mp_error->payload); } static uint32_t mp_sizeof_error_one(const struct error *error) { uint32_t errcode = box_error_code(error); - - bool is_custom = false; - bool is_access_denied = false; - - if (strcmp(error->type->name, "CustomError") == 0) { - is_custom = true; - } else if (strcmp(error->type->name, "AccessDeniedError") == 0) { - is_access_denied = true; - } - - uint32_t details_num = 6; + int field_count = error->payload.count; + uint32_t map_size = 6 + (field_count > 0); uint32_t data_size = 0; + data_size += mp_sizeof_map(map_size); data_size += mp_sizeof_uint(MP_ERROR_TYPE); data_size += mp_sizeof_str(strlen(error->type->name)); data_size += mp_sizeof_uint(MP_ERROR_LINE); @@ -160,28 +156,15 @@ mp_sizeof_error_one(const struct error *error) data_size += mp_sizeof_uint(MP_ERROR_CODE); data_size += mp_sizeof_uint(errcode); - if (is_access_denied) { - ++details_num; - data_size += mp_sizeof_uint(MP_ERROR_FIELDS); - data_size += mp_sizeof_map(3); - AccessDeniedError *ad_err = type_cast(AccessDeniedError, error); - data_size += mp_sizeof_str(strlen("object_type")); - data_size += mp_sizeof_str(strlen(ad_err->object_type())); - data_size += mp_sizeof_str(strlen("object_name")); - data_size += mp_sizeof_str(strlen(ad_err->object_name())); - data_size += mp_sizeof_str(strlen("access_type")); - data_size += mp_sizeof_str(strlen(ad_err->access_type())); - } else if (is_custom) { - ++details_num; + if (field_count > 0) { data_size += mp_sizeof_uint(MP_ERROR_FIELDS); - data_size += mp_sizeof_map(1); - data_size += mp_sizeof_str(strlen("custom_type")); - data_size += - mp_sizeof_str(strlen(box_error_custom_type(error))); + data_size += mp_sizeof_map(field_count); + for (int i = 0; i < field_count; ++i) { + const struct error_field *f = error->payload.fields[i]; + data_size += mp_sizeof_str(strlen(f->name)); + data_size += f->size; + } } - - data_size += mp_sizeof_map(details_num); - return data_size; } @@ -195,21 +178,10 @@ static char * mp_encode_error_one(char *data, const struct error *error) { uint32_t errcode = box_error_code(error); + int field_count = error->payload.count; + uint32_t map_size = 6 + (field_count > 0); - bool is_custom = false; - bool is_access_denied = false; - - if (strcmp(error->type->name, "CustomError") == 0) { - is_custom = true; - } else if (strcmp(error->type->name, "AccessDeniedError") == 0) { - is_access_denied = true; - } - - uint32_t details_num = 6; - if (is_access_denied || is_custom) - ++details_num; - - data = mp_encode_map(data, details_num); + data = mp_encode_map(data, map_size); data = mp_encode_uint(data, MP_ERROR_TYPE); data = mp_encode_str0(data, error->type->name); data = mp_encode_uint(data, MP_ERROR_LINE); @@ -223,21 +195,15 @@ mp_encode_error_one(char *data, const struct error *error) data = mp_encode_uint(data, MP_ERROR_CODE); data = mp_encode_uint(data, errcode); - if (is_access_denied) { - data = mp_encode_uint(data, MP_ERROR_FIELDS); - data = mp_encode_map(data, 3); - AccessDeniedError *ad_err = type_cast(AccessDeniedError, error); - data = mp_encode_str0(data, "object_type"); - data = mp_encode_str0(data, ad_err->object_type()); - data = mp_encode_str0(data, "object_name"); - data = mp_encode_str0(data, ad_err->object_name()); - data = mp_encode_str0(data, "access_type"); - data = mp_encode_str0(data, ad_err->access_type()); - } else if (is_custom) { + if (field_count > 0) { data = mp_encode_uint(data, MP_ERROR_FIELDS); - data = mp_encode_map(data, 1); - data = mp_encode_str0(data, "custom_type"); - data = mp_encode_str0(data, box_error_custom_type(error)); + data = mp_encode_map(data, field_count); + for (int i = 0; i < field_count; ++i) { + const struct error_field *f = error->payload.fields[i]; + data = mp_encode_str0(data, f->name); + memcpy(data, f->data, f->size); + data += f->size; + } } return data; } @@ -254,72 +220,50 @@ error_build_xc(struct mp_error *mp_error) struct error *err = NULL; if (mp_error->type == NULL || mp_error->message == NULL || mp_error->file == NULL) { -missing_fields: diag_set(ClientError, ER_INVALID_MSGPACK, "Missing mandatory error fields"); return NULL; } if (strcmp(mp_error->type, "ClientError") == 0) { - err = new ClientError(mp_error->file, mp_error->line, - ER_UNKNOWN); + err = new ClientError(); } else if (strcmp(mp_error->type, "CustomError") == 0) { - if (mp_error->custom_type == NULL) - goto missing_fields; - err = new CustomError(mp_error->file, mp_error->line, - mp_error->custom_type, mp_error->code); + err = new CustomError(); } else if (strcmp(mp_error->type, "AccessDeniedError") == 0) { - if (mp_error->ad_access_type == NULL || - mp_error->ad_object_type == NULL || - mp_error->ad_object_name == NULL) - goto missing_fields; - err = new AccessDeniedError(mp_error->file, mp_error->line, - mp_error->ad_access_type, - mp_error->ad_object_type, - mp_error->ad_object_name, "", - false); + err = new AccessDeniedError(); } else if (strcmp(mp_error->type, "XlogError") == 0) { - err = new XlogError(&type_XlogError, mp_error->file, - mp_error->line); + err = new XlogError(); } else if (strcmp(mp_error->type, "XlogGapError") == 0) { - err = new XlogGapError(mp_error->file, mp_error->line, - mp_error->message); + err = new XlogGapError(); } else if (strcmp(mp_error->type, "SystemError") == 0) { - err = new SystemError(mp_error->file, mp_error->line, - "%s", mp_error->message); + err = new SystemError(); } else if (strcmp(mp_error->type, "SocketError") == 0) { - err = new SocketError(mp_error->file, mp_error->line, "", ""); - error_format_msg(err, "%s", mp_error->message); + err = new SocketError(); } else if (strcmp(mp_error->type, "OutOfMemory") == 0) { - err = new OutOfMemory(mp_error->file, mp_error->line, - 0, "", ""); + err = new OutOfMemory(); } else if (strcmp(mp_error->type, "TimedOut") == 0) { - err = new TimedOut(mp_error->file, mp_error->line); + err = new TimedOut(); } else if (strcmp(mp_error->type, "ChannelIsClosed") == 0) { - err = new ChannelIsClosed(mp_error->file, mp_error->line); + err = new ChannelIsClosed(); } else if (strcmp(mp_error->type, "FiberIsCancelled") == 0) { - err = new FiberIsCancelled(mp_error->file, mp_error->line); + err = new FiberIsCancelled(); } else if (strcmp(mp_error->type, "LuajitError") == 0) { - err = new LuajitError(mp_error->file, mp_error->line, - mp_error->message); + err = new LuajitError(); } else if (strcmp(mp_error->type, "IllegalParams") == 0) { - err = new IllegalParams(mp_error->file, mp_error->line, - "%s", mp_error->message); + err = new IllegalParams(); } else if (strcmp(mp_error->type, "CollationError") == 0) { - err = new CollationError(mp_error->file, mp_error->line, - "%s", mp_error->message); + err = new CollationError(); } else if (strcmp(mp_error->type, "SwimError") == 0) { - err = new SwimError(mp_error->file, mp_error->line, - "%s", mp_error->message); + err = new SwimError(); } else if (strcmp(mp_error->type, "CryptoError") == 0) { - err = new CryptoError(mp_error->file, mp_error->line, - "%s", mp_error->message); + err = new CryptoError(); } else { - err = new ClientError(mp_error->file, mp_error->line, - ER_UNKNOWN); + err = new ClientError(); } err->code = mp_error->code; err->saved_errno = mp_error->saved_errno; + error_set_location(err, mp_error->file, mp_error->line); + error_move_payload(err, &mp_error->payload); error_format_msg(err, "%s", mp_error->message); return err; } @@ -350,12 +294,6 @@ mp_decode_and_copy_str(const char **data, struct region *region) return region_strdup(region, str, str_len);; } -static inline bool -str_nonterm_is_eq(const char *l, const char *r, uint32_t r_len) -{ - return r_len == strlen(l) && memcmp(l, r, r_len) == 0; -} - static int mp_decode_error_fields(const char **data, struct mp_error *mp_err, struct region *region) @@ -363,35 +301,16 @@ mp_decode_error_fields(const char **data, struct mp_error *mp_err, if (mp_typeof(**data) != MP_MAP) return -1; uint32_t map_sz = mp_decode_map(data); - const char *key; - uint32_t key_len; for (uint32_t i = 0; i < map_sz; ++i) { - if (mp_typeof(**data) != MP_STR) + uint32_t svp = region_used(region); + const char *key = mp_decode_and_copy_str(data, region); + if (key == NULL) return -1; - key = mp_decode_str(data, &key_len); - if (str_nonterm_is_eq("object_type", key, key_len)) { - mp_err->ad_object_type = - mp_decode_and_copy_str(data, region); - if (mp_err->ad_object_type == NULL) - return -1; - } else if (str_nonterm_is_eq("object_name", key, key_len)) { - mp_err->ad_object_name = - mp_decode_and_copy_str(data, region); - if (mp_err->ad_object_name == NULL) - return -1; - } else if (str_nonterm_is_eq("access_type", key, key_len)) { - mp_err->ad_access_type = - mp_decode_and_copy_str(data, region); - if (mp_err->ad_access_type == NULL) - return -1; - } else if (str_nonterm_is_eq("custom_type", key, key_len)) { - mp_err->custom_type = - mp_decode_and_copy_str(data, region); - if (mp_err->custom_type == NULL) - return -1; - } else { - mp_next(data); - } + const char *value = *data; + mp_next(data); + uint32_t value_len = *data - value; + error_payload_set_mp(&mp_err->payload, key, value, value_len); + region_truncate(region, svp); } return 0; } @@ -462,6 +381,7 @@ mp_decode_error_one(const char **data) } finish: region_truncate(region, region_svp); + mp_error_destroy(&mp_err); return err; error: diff --git a/src/lib/core/diag.c b/src/lib/core/diag.c index 217c3ae7e..b6fa1f5bb 100644 --- a/src/lib/core/diag.c +++ b/src/lib/core/diag.c @@ -119,18 +119,21 @@ error_create(struct error *e, 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; - } else { - e->file[0] = '\0'; - e->line = 0; - } + if (file == NULL) + file = ""; + error_set_location(e, file, line); e->errmsg[0] = '\0'; e->cause = NULL; e->effect = NULL; } +void +error_set_location(struct error *e, const char *file, int line) +{ + snprintf(e->file, sizeof(e->file), "%s", file); + e->line = line; +} + struct diag * diag_get(void) { diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h index 03bd223e1..40d934c19 100644 --- a/src/lib/core/diag.h +++ b/src/lib/core/diag.h @@ -190,6 +190,12 @@ error_field_unset(struct error *e, const char *name) error_payload_unset(&e->payload, name); } +static inline void +error_move_payload(struct error *e, struct error_payload *src) +{ + error_payload_move(&e->payload, src); +} + /** * Unlink error from its effect. For instance: * e1 -> e2 -> e3 -> e4 (e1:set_prev(e2); e2:set_prev(e3) ...) @@ -243,6 +249,9 @@ error_create(struct error *e, const struct type_info *type, const char *file, unsigned line); +void +error_set_location(struct error *e, const char *file, int line); + void error_format_msg(struct error *e, const char *format, ...); diff --git a/src/lib/core/exception.h b/src/lib/core/exception.h index 7277b2784..28bc7ef05 100644 --- a/src/lib/core/exception.h +++ b/src/lib/core/exception.h @@ -91,6 +91,12 @@ public: SystemError(const char *file, unsigned line, const char *format, ...); + + SystemError() + :Exception(&type_SystemError, NULL, 0) + { + } + protected: SystemError(const struct type_info *type, const char *file, unsigned line); }; @@ -100,6 +106,12 @@ class SocketError: public SystemError { public: SocketError(const char *file, unsigned line, const char *socketname, const char *format, ...); + + SocketError() + :SystemError(&type_SocketError, file, line) + { + } + virtual void raise() { throw this; @@ -111,18 +123,36 @@ public: OutOfMemory(const char *file, unsigned line, size_t amount, const char *allocator, const char *object); + + OutOfMemory() + :SystemError(&type_OutOfMemory, NULL, 0) + { + } + virtual void raise() { throw this; } }; class TimedOut: public SystemError { public: TimedOut(const char *file, unsigned line); + + TimedOut() + :SystemError(&type_TimedOut, NULL, 0) + { + } + virtual void raise() { throw this; } }; class ChannelIsClosed: public Exception { public: ChannelIsClosed(const char *file, unsigned line); + + ChannelIsClosed() + :Exception(&type_ChannelIsClosed, NULL, 0) + { + } + virtual void raise() { throw this; } }; @@ -133,6 +163,12 @@ public: class FiberIsCancelled: public Exception { public: FiberIsCancelled(const char *file, unsigned line); + + FiberIsCancelled() + :Exception(&type_FiberIsCancelled, NULL, 0) + { + } + virtual void log() const; virtual void raise() { throw this; } }; @@ -141,12 +177,24 @@ class LuajitError: public Exception { public: LuajitError(const char *file, unsigned line, const char *msg); + + LuajitError() + :Exception(&type_LuajitError, NULL, 0) + { + } + virtual void raise() { throw this; } }; class IllegalParams: public Exception { public: IllegalParams(const char *file, unsigned line, const char *format, ...); + + IllegalParams() + :Exception(&type_IllegalParams, NULL, 0) + { + } + virtual void raise() { throw this; } }; @@ -154,18 +202,36 @@ class CollationError: public Exception { public: CollationError(const char *file, unsigned line, const char *format, ...); + + CollationError() + :Exception(&type_CollationError, NULL, 0) + { + } + virtual void raise() { throw this; } }; class SwimError: public Exception { public: SwimError(const char *file, unsigned line, const char *format, ...); + + SwimError() + :Exception(&type_SwimError, NULL, 0) + { + } + virtual void raise() { throw this; } }; class CryptoError: public Exception { public: CryptoError(const char *file, unsigned line, const char *format, ...); + + CryptoError() + :Exception(&type_CryptoError, NULL, 0) + { + } + virtual void raise() { throw this; } }; diff --git a/test/unit/mp_error.cc b/test/unit/mp_error.cc index fe0cd49b9..e6560883e 100644 --- a/test/unit/mp_error.cc +++ b/test/unit/mp_error.cc @@ -34,9 +34,11 @@ #include "memory.h" #include "msgpuck.h" #include "mp_extension_types.h" +#include "random.h" #include "tt_static.h" #include "small/ibuf.h" #include "mpstream/mpstream.h" +#include "uuid/tt_uuid.h" #include "box/error.h" #include "box/mp_error.h" @@ -362,7 +364,7 @@ void test_fail_not_enough_fields() { header(); - plan(2); + plan(4); char buffer[2048]; memset(buffer, 0, sizeof(buffer)); @@ -383,8 +385,12 @@ test_fail_not_enough_fields() const char *pos = buffer; struct error *unpacked = error_unpack(&pos, len); - is(unpacked, NULL, "check not enough additional fields"); - ok(!diag_is_empty(diag_get()), "error about parsing problem is set"); + isnt(unpacked, NULL, "check lack of fields"); + is(strcmp(error_field_get_str(unpacked, "object_type"), + err.ad_object_type), 0, "object type"); + is(strcmp(error_field_get_str(unpacked, "access_type"), + err.ad_access_type), 0, "access type"); + is(error_field_get_str(unpacked, "object_name"), NULL, "object name"); check_plan(); footer(); } @@ -455,6 +461,65 @@ test_unknown_additional_fields() footer(); } +static void +test_payload(void) +{ + header(); + plan(11); + char buffer[2048]; + memset(buffer, 0, sizeof(buffer)); + + struct error *e = new ClientError(); + error_ref(e); + e->code = 42; + e->saved_errno = 1; + error_format_msg(e, "msg"); + error_set_location(e, "file", 2); + error_field_set_str(e, "key1", "1"); + error_field_set_uint(e, "key2", 1); + error_field_set_int(e, "key3", -1); + error_field_set_double(e, "key4", 1.5); + error_field_set_bool(e, "key5", true); + struct tt_uuid uuid; + tt_uuid_create(&uuid); + error_field_set_uuid(e, "key6", &uuid); + + mp_encode_error(buffer, e); + error_unref(e); + + int8_t type; + const char *data = buffer; + mp_decode_extl(&data, &type); + e = error_unpack_unsafe(&data); + error_ref(e); + + is(e->code, 42, "code"); + is(e->saved_errno, 1, "errno"); + is(strcmp(e->errmsg, "msg"), 0, "msg"); + is(e->line, 2, "line"); + is(strcmp(e->file, "file"), 0, "file"); + is(strcmp(error_field_get_str(e, "key1"), "1"), 0, "key str"); + uint64_t val_uint; + ok(error_field_get_uint(e, "key2", &val_uint) && val_uint == 1, + "key uint"); + int64_t val_int; + ok(error_field_get_int(e, "key3", &val_int) && val_int == -1, + "key int"); + double val_dbl; + ok(error_field_get_double(e, "key4", &val_dbl) && val_dbl == 1.5, + "key double"); + bool val_bool; + ok(error_field_get_bool(e, "key5", &val_bool) && val_bool, "key bool"); + struct tt_uuid val_uuid; + ok(error_field_get_uuid(e, "key6", &val_uuid) && + tt_uuid_is_equal(&uuid, &val_uuid), "key uuid"); + + error_unref(e); + + check_plan(); + footer(); +} + static int mp_fprint_ext_test(FILE *file, const char **data, int depth) { @@ -723,7 +788,8 @@ int main(void) { header(); - plan(6); + plan(7); + random_init(); memory_init(); fiber_init(fiber_c_invoke); @@ -732,10 +798,12 @@ main(void) test_fail_not_enough_fields(); test_unknown_fields(); test_unknown_additional_fields(); + test_payload(); test_mp_print(); fiber_free(); memory_free(); + random_free(); footer(); return check_plan(); } diff --git a/test/unit/mp_error.result b/test/unit/mp_error.result index 0582458d3..356d2dc97 100644 --- a/test/unit/mp_error.result +++ b/test/unit/mp_error.result @@ -1,5 +1,5 @@ *** main *** -1..6 +1..7 *** test_stack_error_decode *** 1..17 ok 1 - check CustomError @@ -27,9 +27,11 @@ ok 1 - subtests ok 2 - subtests *** test_decode_unknown_type: done *** *** test_fail_not_enough_fields *** - 1..2 - ok 1 - check not enough additional fields - ok 2 - error about parsing problem is set + 1..4 + ok 1 - check lack of fields + ok 2 - object type + ok 3 - access type + ok 4 - object name ok 3 - subtests *** test_fail_not_enough_fields: done *** *** test_unknown_fields *** @@ -41,6 +43,21 @@ ok 4 - subtests ok 1 - check unknown additional field ok 5 - subtests *** test_unknown_additional_fields: done *** + *** test_payload *** + 1..11 + ok 1 - code + ok 2 - errno + ok 3 - msg + ok 4 - line + ok 5 - file + ok 6 - key str + ok 7 - key uint + ok 8 - key int + ok 9 - key double + ok 10 - key bool + ok 11 - key uuid +ok 6 - subtests + *** test_payload: done *** *** test_mp_print *** 1..60 # zero depth, normal error @@ -109,6 +126,6 @@ ok 5 - subtests ok 58 - mp_fprint depth 0 correct length ok 59 - mp_fprint depth 0 correct prefix and suffix ok 60 - mp_fprint depth 0 correct object in the middle -ok 6 - subtests +ok 7 - subtests *** test_mp_print: done *** *** main: done *** -- 2.24.3 (Apple Git-128)
next prev parent reply other threads:[~2021-11-05 23:59 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-11-05 23:56 [Tarantool-patches] [PATCH 0/9] ER_READONLY reason Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 1/9] diag: return created error from diag_set() Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 2/9] error: introduce error_payload Vladislav Shpilevoy via Tarantool-patches 2021-11-08 15:14 ` Serge Petrenko via Tarantool-patches 2021-11-11 23:50 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-12 6:29 ` Serge Petrenko via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 3/9] error: move code to struct error from ClientError Vladislav Shpilevoy via Tarantool-patches 2021-11-08 15:15 ` Serge Petrenko via Tarantool-patches 2021-11-11 23:50 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-12 6:31 ` Serge Petrenko via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 4/9] error: use error_payload to store optional members Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` Vladislav Shpilevoy via Tarantool-patches [this message] 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 6/9] error: use error_payload in Lua Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 7/9] luatest: copy config in cluster:build_server() Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 8/9] luatest: add new helpers for 'server' object Vladislav Shpilevoy via Tarantool-patches 2021-11-08 15:16 ` Serge Petrenko via Tarantool-patches 2021-11-11 23:51 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-05 23:56 ` [Tarantool-patches] [PATCH 9/9] box: enrich ER_READONLY with new details Vladislav Shpilevoy via Tarantool-patches 2021-11-06 19:30 ` Cyrill Gorcunov via Tarantool-patches 2021-11-07 16:45 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-07 20:19 ` Cyrill Gorcunov via Tarantool-patches 2021-11-08 15:18 ` Serge Petrenko via Tarantool-patches 2021-11-11 23:52 ` Vladislav Shpilevoy via Tarantool-patches 2021-11-08 14:25 ` [Tarantool-patches] [PATCH 0/9] ER_READONLY reason Vladimir Davydov 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=7adc72ff7c2de0a662e2591234eade251fb83f27.1636156453.git.v.shpilevoy@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=sergepetrenko@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --cc=vdavydov@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 5/9] error: use error_payload in MessagePack codecs' \ /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