Combine – error type mismatch when using flatMap

Advertisements

I’m pretty new to Combine. I’m facing the problem with compilator complaining about error types mismatch in such a situation:

struct Service {
   func save(text: String) -> AnyPublisher<Void, Error> {
      Just(())
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
   }
}

let service = Service()
let saveTrigger = PassthroughSubject<Void, Never>()

let cancellable = saveTrigger.map { "text to save"}
   .flatMap { service.save(text: $0) }
   .sink {
       print("Saved")
   }

saveTrigger.send(())

It fails to build with error:
No exact matches in call to instance method 'flatMap'

If I use setFailureType like this:

let cancellable = saveTrigger.map { "text to save"}
   .setFailureType(to: Error.self)
   .flatMap { service.save(text: $0) }
   .sink {
       print("Saved")
   }

I end up with different error:
Referencing instance method 'sink(receiveValue:)' on 'Publisher' requires the types 'any Error' and 'Never' be equivalent

Any idea how to solve the problem?

>Solution :

The overload of sink that you are trying to call is only available when the publisher Never fails.

Available when Failure is Never.

This is also hinted by the second error message you got.

However, since you flat mapped the publisher to the publisher that save returns, which can fail, the resulting publisher of the flat map can fail too.

This means that you need to use the other overload of sink, the one that allows you to handle errors:

.sink { completion in
    if case let .failure(error) = completion {
        print("Error occurred: \(error)")
    }
} receiveValue: { _ in
    print("Saved")
}

Leave a ReplyCancel reply