I'm trying to handle the responses that arrive from a DataTaskPublisher
reading its response status code.
When status code is greater than 299, I'd like to return a ServiceError
type as Failure. In every examples that I've seen I've used .mapError
and .catch
... in this specific case, from a .flatMap
, I really don't know how to handle the publisher response to return the Error instead of the TResponse
...
return URLSession.DataTaskPublisher(request: urlRequest, session: .shared)
.mapError{error in return ServiceError.request}
.flatMap{ data, response -> AnyPublisher<TResponse, ServiceError> in
if let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode){
return Just(data)
.decode(type: TResponse.self, decoder: JSONDecoder())
.mapError{error in return ServiceError.decode}
.eraseToAnyPublisher()
}else{
//???? HOW TO HANDLE THE ERROR?
}
}
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
If I correctly understood your goal, you need something like
}else{
return Fail(error: ServiceError.badServiceReply)
.eraseToAnyPublisher()
}
Simple example:
URLSession.shared
.dataTaskPublisher(for: URL(string: "https://www.google.com")!)
.receive(on: DispatchQueue.main)
.flatMap { _ in
Fail(error: URLError(URLError.unsupportedURL)).eraseToAnyPublisher()
} //for the sake of the demo
.replaceError(with: "An error occurred") //this sets Failure to Never
.assign(to: \.stringValue, on: self)
.store(in: &cancellableBag)
would always assign string "An error occurred" due to remap to Fail
publisher