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()
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.