Skip to content
This repository has been archived by the owner on Jul 3, 2022. It is now read-only.

Cannot return a future with a different error type by chaining calls with flatMap #115

Closed
NickAger opened this issue Feb 10, 2016 · 1 comment

Comments

@NickAger
Copy link

To illustrate the problem I've modified one of the methods in the test suite, substituting NSError for NoError

    func testFlatMapByPassingFunction() {
        let e = self.expectation()

        func toString(n: Int) -> Future<String, NSError> {
            return Future<String, NSError>(value: "\(n)")
        }

        let n = 1
        let flatMapped = Future<Int, NoError>(value: n).flatMap(toString)

        flatMapped.onSuccess { s in
            XCTAssertEqual(s, "\(n)", "strings are not equal")
            e.fulfill()
        }

        self.waitForExpectationsWithTimeout(2, handler: nil)
    }

Which result in the error: Cannot invoke 'flatMap' with an argument list of type '((Int) -> Future<String, NSError>)'

@NickAger
Copy link
Author

My apologies, I now see why this isn't possible as the resultant future from one or more chained flatMap calls needs to have some kind of consistent error type to allow errors to propagate through the composition.

I stole the idea of a type erasure 'AnyError' type from #108 pull request:

public struct AnyError : ErrorType {
    public let cause:ErrorType

    public init(cause:ErrorType) {
        self.cause = cause
    }
}

Then previous example I gave becomes:

    func testFlatMapByPassingFunction() {
        let e = self.expectation()

        func toString(n: Int) -> Future<String, AnyError > {
            return Future<String, AnyError >(value: "\(n)")
        }

        let n = 1
        let flatMapped = Future<Int, AnyError >(value: n).flatMap(toString)

        flatMapped.onSuccess { s in
            XCTAssertEqual(s, "\(n)", "strings are not equal")
            e.fulfill()
        }

        self.waitForExpectationsWithTimeout(2, handler: nil)
    }

and all works as expected. If only Swift allowed protocol to be used as type parameters ... :

Using 'ErrorType' as a concrete type conforming to protocol 'ErrorType' is not allowed

Thanks again for a great framework - its dramatically simplified my code.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant