zserge / lua-promises

A+ promises in Lua
https://zserge.com/lua-promises/
MIT License
222 stars 35 forks source link

Rejection propagation is incorrect #3

Open stakira opened 8 years ago

stakira commented 8 years ago
local deferred = require("deferred")

local d = deferred:new()

local function f1()
    return d
end

local function f2()
    return f1():next(
        function(res)
            return (res or "") .. "f2"
        end,
        function(err)
            print("f2 err")
            return err
        end
    )
end

local function f3()
    return f2():next(
        function(res)
            return res .. "f3"
        end,
        function(err)
            print("f3 err")
            return err
        end
    )
end

f3():next(
    function(res)
        print("suc", res)
    end,
    function(err)
        print("fail", err)
    end
)

d:reject("fail error reject")
Failure: fail error reject
suc f2f3

Tried both Lua 5.1.5 and 5.2.4, same results.

Even though I don't know if returning in error callback is the way to pass error to next stage, obviously error handling branch in f2() doesn't get called at all. Could you please explain this? Thanks.

zserge commented 7 years ago

Please accept my apologies for a very late reply.

The fact that you're seeing no error-handling branch is really confusing, because I ran exactly the same code on Lua 5.1 and 5.3 (ubuntu amd64) and I clearly see f2 err to be printed on screen as expected.

As for the error propagation - the correct way would be to "throw" the same error again, e.g. error(err) instead of return err. Then I see f3 err and fail messages in the output.

Below is the code I used to reproduce it:

local deferred = require("deferred")

local d = deferred:new()

local function f1()
    return d
end

local function f2()
    return f1():next(
        function(res)
            return (res or "") .. "f2"
        end,
        function(err)
            print("f2 err")
            error(err)
        end
    )
end

local function f3()
    return f2():next(
        function(res)
            return res .. "f3"
        end,
        function(err)
            print("f3 err")
            error(err)
        end
    )
end

f3():next(
    function(res)
        print("suc", res)
    end,
    function(err)
        print("fail", err)
    end
)

d:reject("fail error reject")

The output is (same for Lua 5.3):

$ lua5.1 x.lua
f2 err
f3 err
fail    x.lua:28: x.lua:16: fail error reject