我正在尝试处理从DataTaskPublisher
读取其响应状态代码而来的响应。
当状态码大于299时,我想返回ServiceError
类型作为Failure。在我看到的每个示例中,我都使用过.mapError
的{{1}}和.catch
...在这种特定情况下,我真的不知道如何处理发布者响应以返回错误而不是.flatMap
...
TResponse
答案 0 :(得分:2)
enum ServiceErrors {
case internalError(_ statusCode: Int)
case severError(_ statusCode: Int)
}
return URLSession.shared.dataTaskPublisher(for: urlRequest)
.tryMap { data, response in
guard let httpResponse = response as? HTTPURLResponse,
200..<300 ~= httpResponse.statusCode else {
switch (response as! HTTPURLResponse).statusCode {
case (400...499):
throw ServiceErrors.internalError((response as! HTTPURLResponse).statusCode)
default:
throw ServiceErrors.serverError((response as! HTTPURLResponse).statusCode)
}
}
return data
}
.mapError { $0 as! ServiceErrors }
.decode(type: T.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
我依靠此链接来创建我的错误处理程序https://gist.github.com/stinger/7cb1a81facf7f846e3d53f60be34dd1e
答案 1 :(得分:1)
如果我正确理解了您的目标,则需要类似
}else{
return Fail(error: ServiceError.badServiceReply)
.eraseToAnyPublisher()
}
简单的例子:
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)
由于重新映射到Fail
发布者,总是会分配字符串“发生错误”