[tarantool-patches] [PATCH v3 1/4] error: introduce error rebulding API

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Tue May 15 22:54:05 MSK 2018


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<error_name> 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)





More information about the Tarantool-patches mailing list