In the Combine framework, we can throw a generic Error protocol type while using tryMap.
However, how can we be more specific about the Error type?
For example,
let publisher = urlSession.dataTaskPublisher(for: request).tryMap { (data, response) -> (Data, HTTPURLResponse) in
guard let response = response as? HTTPURLResponse else {
throw URLError(.cannotParseResponse)
}
return (data, response)
}
How to specify the Error type of this publisher? I'd like to use URLError instead of Error.
I found the method setFailureType(to:) in the Combine framework. However, it is not available to tryMap(_:).
setFailureType(to:) is only to force the failure type of a publisher with failure type Never. tryMap always uses Error as the error type because any Error could be thrown in the closure body, so you need to use mapError to force the URLError type:
let map_error = publisher.mapError({ error -> URLError in
switch (error) {
case let url_error as URLError:
return url_error
default:
return URLError(.unknown)
}
})
You can also accomplish this with flatMap. This will allow you to specify both the Output and Error type at once, like so:
struct SomeResponseType {
let data: Data
let response: HTTPURLResponse
}
let publisher = urlSession.dataTaskPublisher(for: request)
.flatMap { (data, response) -> AnyPublisher<SomeResponseType, URLError > in
guard let response = response as? HTTPURLResponse else {
return Fail(error: URLError(.cannotParseResponse))
.eraseToAnyPublisher()
}
return Just(SomeResponseType(data: data, response: response)
.setFailureType(to: URLError)
.eraseToAnyPublisher()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With