Skip to content

Commit

Permalink
box/lua: implement inheritance of error payload fields
Browse files Browse the repository at this point in the history
Suppose an error has a cause with some payload fields, for example:
  local e1 = box.error.new{'e1', foo = 'bar'} -- cause
  local e2 = box.error.new{'e2', prev = e1}   -- effect

Now it is possible to access cause payload fields via e2 directly:
  e2.foo -- 'bar'

While looking for a payload field with a given name, we always stop at
the topmost (closest to the effect) field. If there's a field with the
same name deeper in the stack it is masked.

Closes tarantool#9106

@TarantoolBot document
Title: Document inheritance of error payload fields
Product: Tarantool
Since: 3.1
Root document: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_error/error_object/

[Link to the design document](https://www.notion.so/tarantool/Error-subsystem-improvements-90faa0a4714b4143abaf8bed2c10b2fc?pvs=4#c080fe2ac28b46c8b0eda7234a8852ce)
  • Loading branch information
Gumix authored and sergepetrenko committed Feb 21, 2024
1 parent 709938a commit d592f26
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
4 changes: 4 additions & 0 deletions changelogs/unreleased/gh-9106-error-payload-inheritance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## feature/lua

* Now it is possible to access a payload field of an error's cause directly
from the error (gh-9106).
11 changes: 8 additions & 3 deletions src/lua/error.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,14 @@ local function error_index(err, key)
if getter ~= nil then
return getter(err)
end
local f = ffi.C.error_find_field(err, key)
if f ~= nil then
return mp_decode(f._data)
-- Look for a payload field, starting from the topmost error in the stack.
local cur_err = err
while cur_err ~= nil do
local f = ffi.C.error_find_field(cur_err, key)
if f ~= nil then
return mp_decode(f._data)
end
cur_err = cur_err.prev
end
end

Expand Down
11 changes: 11 additions & 0 deletions test/box-luatest/error_subsystem_improvements_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,14 @@ g.test_methods_masking = function()
t.assert_equals(e:unpack().set_prev, 'hack')
t.assert_equals(e:unpack().__serialize, 'hack')
end

-- Test that payload fields of a cause are inherited by the effect (gh-9106).
g.test_payload_inheritance = function()
local e1 = box.error.new({foo = 11, bar = 22})
local e2 = box.error.new({bar = 33, baz = 44, prev = e1})
local e3 = box.error.new({baz = 55, prev = e2})

t.assert_equals(e3.foo, 11) -- Inherited from e1.
t.assert_equals(e3.bar, 33) -- Inherited from e2.
t.assert_equals(e3.baz, 55) -- Own payload field.
end

0 comments on commit d592f26

Please sign in to comment.