evaera / roblox-lua-promise

Promise implementation for Roblox
https://eryn.io/roblox-lua-promise/
MIT License
275 stars 74 forks source link

Error in finally handler does not propagate to subsequent catch after a :timeout #96

Closed kylepo99 closed 11 months ago

kylepo99 commented 11 months ago

if an error is thrown inside a finally handler of a promise that has been timed out, the promise is cancelled and the Timeout Error does not propagate to the subsequent catch handlers. This leads to unexpected silent failures that gives the appearance the promise is yielding forever in cases where timeout rejection is expected

Error inside handler

    Promises.resolve():andThen(function(...)
          return Promises.delay(10):finally(function()
            error("Something went wrong") -- This will silently Error
        end)
    end)
    :timeout(1)
    :catch(function() -- Silent failure
        warn("The Promise was Rejected :( ") -- This won't run
    end)

No Error inside handler, Works as intended.

    Promises.resolve():andThen(function(...)
          return Promises.delay(10):finally(function()
               warn("Did some work here")
        end)
    end)
    :timeout(1)
    :catch(function() -- This will run!
        warn("The Promise was Rejected :( ") -- Promise was rejected because of Timeout
    end)

In the second example, if there's no error in the finally block, the catch handler is correctly invoked due to the :timeout. The expected behavior is for the catch handler to always be triggered by the :timeout, even if there is an error in the finally block.

evaera commented 11 months ago

Should be fixed on the master branch now. Finally error was being propagated into the internals of the Promise library and stopping execution of the code that keeps things flowing down the Promise chain. Thanks for finding this

evaera commented 11 months ago

Turns out my fix broke something else so I fixed the fix... the world should be right again