[Tarantool-patches] [PATCH v2 3/5] error: Increase the number of fields transmitted through IPROTO

Leonid Vasiliev lvasiliev at tarantool.org
Fri Apr 10 11:10:41 MSK 2020


Has been added IPROTO_ERROR_TRACEBACK and IPROTO_ERROR_CUSTOM_TYPE
fields to IPROTO_ERROR_STACK for transfering through network
a backtrace and custom type.

Needed for #4398
---
 src/box/iproto_constants.h |  2 ++
 src/box/lua/error.cc       | 23 +++++++++++++++++++++++
 src/box/lua/net_box.lua    | 21 ++++++++++++++++++++-
 src/box/xrow.c             | 19 ++++++++++++++++++-
 4 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/src/box/iproto_constants.h b/src/box/iproto_constants.h
index 7ed8296..7daa980 100644
--- a/src/box/iproto_constants.h
+++ b/src/box/iproto_constants.h
@@ -154,6 +154,8 @@ enum iproto_ballot_key {
 enum iproto_error_key {
 	IPROTO_ERROR_CODE = 0x01,
 	IPROTO_ERROR_MESSAGE = 0x02,
+	IPROTO_ERROR_TRACEBACK = 0x03,
+	IPROTO_ERROR_CUSTOM_TYPE = 0x04,
 };
 
 #define bit(c) (1ULL<<IPROTO_##c)
diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc
index 1bcce1f..27dee7a 100644
--- a/src/box/lua/error.cc
+++ b/src/box/lua/error.cc
@@ -236,6 +236,25 @@ luaT_error_custom_type(lua_State *L)
 }
 
 static int
+luaT_error_set_lua_traceback(lua_State *L)
+{
+	if (lua_gettop(L) < 2)
+		return luaL_error(L, "Usage: box.error.set_lua_traceback"\
+				     "(error, traceback)");
+
+	struct error *e = luaL_checkerror(L, 1);
+
+	if (lua_type(L, 2) == LUA_TSTRING) {
+		error_set_lua_traceback(e, lua_tostring(L, 2));
+	} else {
+		return luaL_error(L, "Usage: box.error.set_lua_traceback"\
+				     "(error, traceback)");
+	}
+
+	return 0;
+}
+
+static int
 luaT_error_clear(lua_State *L)
 {
 	if (lua_gettop(L) >= 1)
@@ -395,6 +414,10 @@ box_lua_error_init(struct lua_State *L) {
 			lua_pushcfunction(L, luaT_error_custom_type);
 			lua_setfield(L, -2, "custom_type");
 		}
+		{
+			lua_pushcfunction(L, luaT_error_set_lua_traceback);
+			lua_setfield(L, -2, "set_lua_traceback");
+		}
 		lua_setfield(L, -2, "__index");
 	}
 	lua_setmetatable(L, -2);
diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua
index 07fa54c..1e0cd7a 100644
--- a/src/box/lua/net_box.lua
+++ b/src/box/lua/net_box.lua
@@ -47,6 +47,8 @@ local IPROTO_ERROR_KEY     = 0x31
 local IPROTO_ERROR_STACK   = 0x52
 local IPROTO_ERROR_CODE    = 0x01
 local IPROTO_ERROR_MESSAGE = 0x02
+local IPROTO_ERROR_TRACEBACK = 0x03
+local IPROTO_ERROR_CUSTOM_TYPE = 0x04
 local IPROTO_GREETING_SIZE = 128
 local IPROTO_CHUNK_KEY     = 128
 local IPROTO_OK_KEY        = 0
@@ -287,7 +289,24 @@ local function create_transport(host, port, user, password, callback,
                     local error = self.response[i]
                     local code = error[IPROTO_ERROR_CODE]
                     local msg = error[IPROTO_ERROR_MESSAGE]
-                    local new_err = box.error.new({code = code, reason = msg})
+                    local custom_type = error[IPROTO_ERROR_CUSTOM_TYPE]
+                    local traceback = error[IPROTO_ERROR_TRACEBACK]
+
+                    local new_err
+                    if custom_type then
+                        new_err = box.error.new({type = custom_type,
+                                                 reason = msg,
+                                                 traceback = false})
+                    else
+                        new_err = box.error.new({code = code,
+                                                 reason = msg,
+                                                 traceback = false})
+                    end
+
+                    if traceback then
+                        box.error.set_lua_traceback(new_err, traceback)
+                    end
+
                     new_err:set_prev(prev)
                     prev = new_err
                 end
diff --git a/src/box/xrow.c b/src/box/xrow.c
index be026a4..cd88e49 100644
--- a/src/box/xrow.c
+++ b/src/box/xrow.c
@@ -494,11 +494,28 @@ mpstream_iproto_encode_error(struct mpstream *stream, const struct error *error)
 	mpstream_encode_uint(stream, IPROTO_ERROR_STACK);
 	mpstream_encode_array(stream, err_cnt);
 	for (const struct error *it = error; it != NULL; it = it->cause) {
-		mpstream_encode_map(stream, 2);
+		/* Code and message are necessary fields */
+		uint32_t map_size = 2;
+		const char *custom_type = NULL;
+		if (it->lua_traceback)
+			++map_size;
+		if (strcmp(box_error_type(it), "CustomError") == 0) {
+			++map_size;
+			custom_type = box_custom_error_type(it);
+		}
+		mpstream_encode_map(stream, map_size);
 		mpstream_encode_uint(stream, IPROTO_ERROR_CODE);
 		mpstream_encode_uint(stream, box_error_code(it));
 		mpstream_encode_uint(stream, IPROTO_ERROR_MESSAGE);
 		mpstream_encode_str(stream, it->errmsg);
+		if (it->lua_traceback) {
+			mpstream_encode_uint(stream, IPROTO_ERROR_TRACEBACK);
+			mpstream_encode_str(stream, it->lua_traceback);
+		}
+		if (custom_type) {
+			mpstream_encode_uint(stream, IPROTO_ERROR_CUSTOM_TYPE);
+			mpstream_encode_str(stream, custom_type);
+		}
 	}
 }
 
-- 
2.7.4



More information about the Tarantool-patches mailing list