From 6d0078d05cdb934b413316082873935b8b4bd00d Mon Sep 17 00:00:00 2001
From: Leonid Vasiliev <lvasiliev@tarantool.org>
Date: Tue, 14 Apr 2020 23:36:57 +0300
Subject: [PATCH] error: update constructors of some errors

We want to have a transparent marshalling through net.box
for errors. To do this, we need to recreate the error
on the client side with the same parameters as on the server.
For convenience, we update AccessDeniedError constructor
which has pointers to static strings and add the XlogGapError
constructor that does not require vclock.

Needed for #4398
---
 src/box/error.cc | 24 +++++++++++++++---------
 src/box/error.h  | 11 ++++++++---
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/box/error.cc b/src/box/error.cc
index 277727db35..c3c2af3abc 100644
--- a/src/box/error.cc
+++ b/src/box/error.cc
@@ -255,6 +255,13 @@ 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)
@@ -283,23 +290,22 @@ AccessDeniedError::AccessDeniedError(const char *file, unsigned int line,
 				     const char *access_type,
 				     const char *object_type,
 				     const char *object_name,
-				     const char *user_name)
+				     const char *user_name,
+				     bool run_trigers)
 	:ClientError(&type_AccessDeniedError, file, line, ER_ACCESS_DENIED)
 {
 	error_format_msg(this, tnt_errcode_desc(m_errcode),
 			 access_type, object_type, object_name, user_name);
 
 	struct on_access_denied_ctx ctx = {access_type, object_type, object_name};
-	trigger_run(&on_access_denied, (void *) &ctx);
 	/*
-	 * We want to use ctx parameters as error parameters
-	 * later, so we have to alloc space for it.
-	 * As m_access_type and m_object_type are constant
-	 * literals they are statically  allocated. We must copy
-	 * only m_object_name.
+	 * Don't run the triggers when create after marshaling
+	 * through network.
 	 */
-	m_object_type = object_type;
-	m_access_type = access_type;
+	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);
 }
 
diff --git a/src/box/error.h b/src/box/error.h
index 461ca0f608..988b982553 100644
--- a/src/box/error.h
+++ b/src/box/error.h
@@ -241,11 +241,14 @@ class AccessDeniedError: public ClientError
 public:
 	AccessDeniedError(const char *file, unsigned int line,
 			  const char *access_type, const char *object_type,
-			  const char *object_name, const char *user_name);
+			  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 *
@@ -268,11 +271,11 @@ class AccessDeniedError: public ClientError
 
 private:
 	/** Type of object the required access was denied to */
-	const char *m_object_type;
+	char *m_object_type;
 	/** Name of object the required access was denied to */
 	char *m_object_name;
 	/** Type of declined access */
-	const char *m_access_type;
+	char *m_access_type;
 };
 
 /**
@@ -302,6 +305,8 @@ 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);
 
 	virtual void raise() { throw this; }
 };
-- 
GitLab