Skip to content

handleWith causes Future chain to be called twice if engage resolve fails.  #44

@skeet70

Description

@skeet70

This is pretty edge case and strange behavior. This was discovered while using the library where the Future in question changed test state. When an assertion in the .engage on that future failed, it caused the handleWith code of the already engaged Future to be called again, which cause the map to be called again, which then blew up because the state had already changed. I pushed a minimal reproduction of the bug on the branch handle-called-out-of-scope.

test("does not get run if engages above this scope throw", (done) => {
            let mapCalledTimes = 0;
            let handleWithCalledTimes = 0;
            const action = Future.of(33)
                .handleWith((e) => {
                    console.log(`failed an infallible future: ${e}`);
                    handleWithCalledTimes++;
                    return Future.of(-1);
                })
                .map((r) => {
                    mapCalledTimes++;
                    return r;
                });

            try {
                action.engage(
                    (e) => {
                        throw e;
                    },
                    (r) => {
                        throw new Error(`oh no, something went wrong after the future has run to completion on ${r}`);
                    }
                );
            } catch (e) {
                expect(handleWithCalledTimes).toBe(0);
                expect(mapCalledTimes).toBe(1);
                done();
            }
        });

That's the test entirely though. The error thrown in the .engage causes the whole chain of the Future the engage was called on to run when it's somehow caught by the handleWith. The same thing happens if you start with a rejected Future, though then everything in the chain is run twice including the handleWith.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions