From b85cf605f3b15dad8915c2916d0e0c834f16a7ea Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov@tarantool.org> Date: Wed, 18 May 2022 10:44:03 +0300 Subject: [PATCH] box: add error code for SSLError Applier uses box_error_code() to for better logging: - It remembers tha last raised error code and skips logging if the new error code is the same. - It logs "will retry every X seconds" only for retryable error codes (for example, ER_SYSTEM) while for non-retryable errors (for example, ER_PROC_LUA) the message isn't logged. box_error_code() returns ER_PROC_LUA for SSLError, which is confusing and would result in inconsistent logging in applier if we made SSLError retryable. Let's add a separate error code for this error (ER_SSL) and introduce a test case that checks that box_error_code() works as expected for all kinds of errors. Follow-up commit a7028dde8589 ("Add SSL iostream stub"). Needed for https://github.com/tarantool/tarantool-ee/issues/107 NO_DOC=internal NO_CHANGELOG=internal --- src/box/errcode.h | 1 + src/box/error.cc | 3 +++ src/lib/core/ssl_error.cc | 15 +++++++++++++ src/lib/core/ssl_error.h | 8 ++++++- test/box/error.result | 1 + test/unit/CMakeLists.txt | 2 +- test/unit/error.c | 45 ++++++++++++++++++++++++++++++++++++++- test/unit/error.result | 15 ++++++++++++- 8 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/box/errcode.h b/src/box/errcode.h index 9438050c1d..ca6cb09c9e 100644 --- a/src/box/errcode.h +++ b/src/box/errcode.h @@ -295,6 +295,7 @@ struct errcode_record { /*240 */_(ER_COMPLEX_FOREIGN_KEY_FAILED, "Foreign key constraint '%s' failed: %s") \ /*241 */_(ER_WRONG_SPACE_UPGRADE_OPTIONS, "Wrong space upgrade options: %s") \ /*242 */_(ER_NO_ELECTION_QUORUM, "Not enough peers connected to start elections: %d out of minimal required %d")\ + /*243 */_(ER_SSL, "%s") \ /* * !IMPORTANT! Please follow instructions at start of the file diff --git a/src/box/error.cc b/src/box/error.cc index 5097a076de..e0b916454b 100644 --- a/src/box/error.cc +++ b/src/box/error.cc @@ -36,6 +36,7 @@ #include "trigger.h" #include "vclock/vclock.h" #include "schema.h" +#include "ssl_error.h" /* {{{ public API */ @@ -213,6 +214,8 @@ ClientError::get_errcode(const struct error *e) return ER_MEMORY_ISSUE; if (type_cast(SystemError, e)) return ER_SYSTEM; + if (type_cast(SSLError, e)) + return ER_SSL; if (type_cast(CollationError, e)) return ER_CANT_CREATE_COLLATION; if (type_cast(XlogGapError, e)) diff --git a/src/lib/core/ssl_error.cc b/src/lib/core/ssl_error.cc index 00cdfe9e9e..d7750888e2 100644 --- a/src/lib/core/ssl_error.cc +++ b/src/lib/core/ssl_error.cc @@ -5,13 +5,28 @@ */ #include "ssl_error.h" +#include <stdarg.h> #include <stddef.h> +#include "diag.h" #include "reflection.h" #include "trivia/config.h" +#include "trivia/util.h" #if defined(ENABLE_SSL) # error unimplemented #endif const struct type_info type_SSLError = make_type("SSLError", NULL); + +struct error * +BuildSSLError(const char *file, unsigned line, const char *format, ...) +{ + void *ptr = xmalloc(sizeof(SSLError)); + SSLError *err = new(ptr) SSLError(file, line); + va_list ap; + va_start(ap, format); + error_vformat_msg(err, format, ap); + va_end(ap); + return err; +} diff --git a/src/lib/core/ssl_error.h b/src/lib/core/ssl_error.h index a684cc066e..c6c78df21f 100644 --- a/src/lib/core/ssl_error.h +++ b/src/lib/core/ssl_error.h @@ -22,12 +22,18 @@ extern "C" { extern const struct type_info type_SSLError; +/** Builds an instance of SSLError with the given message. */ +struct error * +BuildSSLError(const char *file, unsigned line, const char *format, ...); + #if defined(__cplusplus) } /* extern "C" */ class SSLError: public Exception { public: - SSLError(): Exception(&type_SSLError, NULL, 0) {} + SSLError(const char *file, unsigned line) + : Exception(&type_SSLError, file, line) {} + SSLError() : SSLError(NULL, 0) {} virtual void raise() { throw this; } }; diff --git a/test/box/error.result b/test/box/error.result index f50f85c181..05244744c7 100644 --- a/test/box/error.result +++ b/test/box/error.result @@ -461,6 +461,7 @@ t; | 240: box.error.COMPLEX_FOREIGN_KEY_FAILED | 241: box.error.WRONG_SPACE_UPGRADE_OPTIONS | 242: box.error.NO_ELECTION_QUORUM + | 243: box.error.SSL | ... test_run:cmd("setopt delimiter ''"); diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 442597255f..f01557871f 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -64,7 +64,7 @@ target_link_libraries(xmalloc.test unit) add_executable(datetime.test datetime.c) target_link_libraries(datetime.test tzcode core cdt unit) add_executable(error.test error.c core_test_utils.c) -target_link_libraries(error.test unit core) +target_link_libraries(error.test unit core box_error) add_executable(interval.test interval.c core_test_utils.c) target_link_libraries(interval.test core unit) diff --git a/test/unit/error.c b/test/unit/error.c index 55f8f67982..460848df25 100644 --- a/test/unit/error.c +++ b/test/unit/error.c @@ -3,11 +3,17 @@ * * Copyright 2010-2021, Tarantool AUTHORS, please see AUTHORS file. */ +#include "box/error.h" +#include "diag.h" #include "error_payload.h" +#include "fiber.h" +#include "memory.h" #include "mp_uuid.h" #include "msgpuck.h" #include "random.h" +#include "ssl_error.h" #include "unit.h" +#include "vclock/vclock.h" #include <float.h> @@ -441,13 +447,47 @@ test_payload_move(void) footer(); } +static void +test_error_code(void) +{ + header(); + plan(9); + + diag_set(ClientError, ER_READONLY); + is(box_error_code(box_error_last()), ER_READONLY, "ClientError"); + diag_set(OutOfMemory, 42, "foo", "bar"); + is(box_error_code(box_error_last()), ER_MEMORY_ISSUE, "OutOfMemory"); + diag_set(SystemError, "foo"); + is(box_error_code(box_error_last()), ER_SYSTEM, "SystemError"); + diag_set(SocketError, "foo", "bar"); + is(box_error_code(box_error_last()), ER_SYSTEM, "SocketError"); + diag_set(TimedOut); + is(box_error_code(box_error_last()), ER_SYSTEM, "TimedOut"); + diag_set(SSLError, "foo"); + is(box_error_code(box_error_last()), ER_SSL, "SSLError"); + diag_set(CollationError, "foo"); + is(box_error_code(box_error_last()), ER_CANT_CREATE_COLLATION, + "CollationError"); + struct vclock vclock; + vclock_create(&vclock); + diag_set(XlogGapError, &vclock, &vclock); + is(box_error_code(box_error_last()), ER_XLOG_GAP, "XlogGapError"); + diag_set(FiberIsCancelled); + is(box_error_code(box_error_last()), ER_PROC_LUA, "FiberIsCancelled"); + + check_plan(); + footer(); +} + int main(void) { header(); - plan(9); + plan(10); random_init(); + memory_init(); + fiber_init(fiber_c_invoke); test_payload_field_str(); test_payload_field_uint(); @@ -458,7 +498,10 @@ main(void) test_payload_field_mp(); test_payload_clear(); test_payload_move(); + test_error_code(); + fiber_free(); + memory_free(); random_free(); footer(); diff --git a/test/unit/error.result b/test/unit/error.result index daf4e6eb06..4e388c764a 100644 --- a/test/unit/error.result +++ b/test/unit/error.result @@ -1,5 +1,5 @@ *** main *** -1..9 +1..10 *** test_payload_field_str *** 1..15 ok 1 - no fields in the beginning @@ -158,4 +158,17 @@ ok 8 - subtests ok 7 - key ok 9 - subtests *** test_payload_move: done *** + *** test_error_code *** + 1..9 + ok 1 - ClientError + ok 2 - OutOfMemory + ok 3 - SystemError + ok 4 - SocketError + ok 5 - TimedOut + ok 6 - SSLError + ok 7 - CollationError + ok 8 - XlogGapError + ok 9 - FiberIsCancelled +ok 10 - subtests + *** test_error_code: done *** *** main: done *** -- GitLab