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?
sink(receiveValue:)
, which you are trying to call, is only available when the publisher Never
fails.
Available when
Failure
isNever
.
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 sink(receiveCompletion:receiveValue:)
, which allows you to handle errors:
.sink { completion in
if case let .failure(error) = completion {
print("Error occurred: \(error)")
}
} receiveValue: { _ in
print("Saved")
}