I've created this publisher chain:
enum ViewState {
case loading, loaded([Person]), error(String)
}
var viewStatePublisher: AnyPublisher<ViewState, Never> {
service.fetchPeople()
.map { ViewState.loaded($0) }
.eraseToAnyPublisher()
}
fetchPeople
can fail, and I'd like to propagate that down the publisher chain as a ViewState.error(String)
value. Here's a rough idea of what I'm trying to do:
service.fetchPeople()
.mapError { error -> AnyPublisher<ViewState, Never> in
ViewState.error(error.localizedDescription)
}
.map { ViewState.loaded($0) }
.eraseToAnyPublisher()
However, mapError
doesn't work that way. I'm having trouble finding other alternatives to doing this.
You need catch
to replace errors thrown by the upstream publisher with a new downstream Publisher.
Inside the catch
, you can wrap the error in a Just
, which is a Publisher
that emits a single value immediately.
service.fetchPeople()
.map { ViewState.loaded($0) }
.catch { Just(ViewState.error($0.localizedDescription)) }
.eraseToAnyPublisher()