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