From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id AE0EC241E5 for ; Tue, 15 May 2018 15:54:10 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NG_J1wetteLb for ; Tue, 15 May 2018 15:54:10 -0400 (EDT) Received: from smtp54.i.mail.ru (smtp54.i.mail.ru [217.69.128.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 567E923A05 for ; Tue, 15 May 2018 15:54:10 -0400 (EDT) From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH v3 1/4] error: introduce error rebulding API Date: Tue, 15 May 2018 22:54:05 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Some of modules are out of box library and returns their custom or common errors like SocketError, IllegalParams erc. But when the core code is used in the box library, some of errors must be converted into another errors. For example, it would be useful to be able to transform IllegalParams into ClientError. The patch introduces diag_reset, that takes new error type and custom arguments depending on the type. An error, that must be available for rebuilding must have Rebuild method, that takes old error object, and custom arguments. --- src/box/error.cc | 27 +++++++++++++++++++++++++++ src/box/error.h | 5 +++++ src/diag.h | 9 +++++++++ 3 files changed, 41 insertions(+) diff --git a/src/box/error.cc b/src/box/error.cc index 99f519537..bbe3b5236 100644 --- a/src/box/error.cc +++ b/src/box/error.cc @@ -108,6 +108,20 @@ ClientError::ClientError(const type_info *type, const char *file, unsigned line, rmean_collect(rmean_error, RMEAN_ERROR, 1); } +ClientError::ClientError(struct error *last_e, uint32_t errcode) + :Exception(&type_ClientError, last_e->file, last_e->line) +{ + m_errcode = errcode; + /* + * Do not collect error - it was collected already by the + * original error. + */ + int len = strlen(last_e->errmsg); + assert(len < DIAG_ERRMSG_MAX); + memcpy(this->errmsg, last_e->errmsg, len); + this->errmsg[len] = 0; +} + ClientError::ClientError(const char *file, unsigned line, uint32_t errcode, ...) :Exception(&type_ClientError, file, line) @@ -137,6 +151,19 @@ BuildClientError(const char *file, unsigned line, uint32_t errcode, ...) } } +struct error * +RebuildClientError(struct error *last_e, uint32_t errcode) +{ + /* Can not convert OOM. */ + if (last_e->type == &type_OutOfMemory) + return last_e; + try { + return new ClientError(last_e, errcode); + } catch (OutOfMemory *e) { + return e; + } +} + void ClientError::log() const { diff --git a/src/box/error.h b/src/box/error.h index c791e6c6a..5bad1cdc3 100644 --- a/src/box/error.h +++ b/src/box/error.h @@ -44,6 +44,9 @@ BuildAccessDeniedError(const char *file, unsigned int line, const char *access_type, const char *object_type, const char *object_name, const char *user_name); +struct error * +RebuildClientError(struct error *last_e, uint32_t errcode); + /** \cond public */ @@ -164,6 +167,8 @@ public: ClientError(const char *file, unsigned line, uint32_t errcode, ...); + ClientError(struct error *last_e, uint32_t errcode); + static uint32_t get_errcode(const struct error *e); /* client errno code */ int m_errcode; diff --git a/src/diag.h b/src/diag.h index dc6c132d5..85fc1ab21 100644 --- a/src/diag.h +++ b/src/diag.h @@ -263,6 +263,15 @@ BuildUnsupportedIndexFeature(const char *file, unsigned line, diag_add_error(diag_get(), e); \ } while (0) +#define diag_reset(new_class, ...) do { \ + struct diag *d = diag_get(); \ + struct error *last_e = diag_last_error(d); \ + if (last_e->type != &type_##new_class) { \ + last_e = Rebuild##new_class(last_e, ##__VA_ARGS__); \ + diag_add_error(d, last_e); \ + } \ +} while (0) + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ -- 2.15.1 (Apple Git-101)