[Tarantool-patches] [PATCH vshard 4/5] error: introduce from_string
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Fri Dec 17 03:25:30 MSK 2021
vshard.storage.call() and most of the other vshard.storage.*
functions now raise an exception STORAGE_IS_DISABLED when the
storage is disabled.
The router wants to catch it to handle in a special way. But
unfortunately,
- error(obj) in a Lua function is wrapped into LuajitError. 'obj'
is saved into 'message' using its __tostring meta-method.
- It is not possible to create your own error type in a sane way.
These 2 facts mean that the router needs to be able to extract
the original error from LuajitError's message. In vshard errors
are serialized into json, so a valid vshard error, such as
STORAGE_IS_DISABLED, can be extracted from LuajitError's message
if it wasn't truncated due to being too long. For this particular
error it won't happen.
The patch introduces new method vshard.error.from_string() to
perform this extraction for its further usage in router.
Part of #298
---
test/unit/error.result | 18 ++++++++++++++++++
test/unit/error.test.lua | 6 ++++++
vshard/error.lua | 19 +++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/test/unit/error.result b/test/unit/error.result
index bb4e0cc..258b14f 100644
--- a/test/unit/error.result
+++ b/test/unit/error.result
@@ -48,6 +48,24 @@ test_run:grep_log('default', '"reason":"reason","code":11,"type":"ShardingError"
---
- '"reason":"reason","code":11,"type":"ShardingError"'
...
+e = lerror.vshard(lerror.code.STORAGE_IS_DISABLED, 'any reason')
+---
+...
+e = lerror.from_string(tostring(e))
+---
+...
+assert(e.code == lerror.code.STORAGE_IS_DISABLED)
+---
+- true
+...
+assert(e.type == 'ShardingError')
+---
+- true
+...
+assert(e.message == 'Storage is disabled: any reason')
+---
+- true
+...
--
-- Part of gh-100: check `error.vshard`.
--
diff --git a/test/unit/error.test.lua b/test/unit/error.test.lua
index 0a51d33..5e669b6 100644
--- a/test/unit/error.test.lua
+++ b/test/unit/error.test.lua
@@ -19,6 +19,12 @@ log = require('log')
log.info('Log error: %s', vshard_error)
test_run:grep_log('default', '"reason":"reason","code":11,"type":"ShardingError"')
+e = lerror.vshard(lerror.code.STORAGE_IS_DISABLED, 'any reason')
+e = lerror.from_string(tostring(e))
+assert(e.code == lerror.code.STORAGE_IS_DISABLED)
+assert(e.type == 'ShardingError')
+assert(e.message == 'Storage is disabled: any reason')
+
--
-- Part of gh-100: check `error.vshard`.
--
diff --git a/vshard/error.lua b/vshard/error.lua
index 2b97eae..96c4bdd 100644
--- a/vshard/error.lua
+++ b/vshard/error.lua
@@ -244,6 +244,24 @@ local function make_error(e)
end
end
+--
+-- Restore an error object from its string serialization.
+--
+local function from_string(str)
+ -- Error objects in VShard are stringified into json. Hence can restore also
+ -- as json. The only problem is that the json might be truncated if it was
+ -- stored in an error message of a real error object. It is not very
+ -- reliable.
+ local ok, res = pcall(json.decode, str)
+ if not ok then
+ return nil
+ end
+ if type(res) ~= 'table' or type(res.type) ~= 'string' or
+ type(res.code) ~= 'number' or type(res.message) ~= 'string' then
+ return nil
+ end
+ return make_error(res)
+end
local function make_alert(code, ...)
local format = error_message_template[code]
@@ -266,6 +284,7 @@ return {
box = box_error,
vshard = vshard_error,
make = make_error,
+ from_string = from_string,
alert = make_alert,
timeout = make_timeout,
}
--
2.24.3 (Apple Git-128)
More information about the Tarantool-patches
mailing list