開始之前,先建立 Error 與 Function
enum DemoError: Error {case noReason}
func willThrow(_ nb:Int) throws -> String {
throw DemoError.noReason
}
在不使用 Combine 的情形下,我們會這樣處理:
let result:String
do {
result = try willThrow(1)
} catch {
//handle Error
}
甚至有些時候會使用 try!/try?
來快速處理,而在套用 Combine 之後,我們可以用第 14 篇的失敗處理類型
來處理
Just(1)
.tryMap{ try willThrow($0)}
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
fatalError()
case .failure(let error):
print(error)
}
}, receiveValue: {fatalError()})
要使用 Result 時,需要一個幫助的
extension Publisher {
typealias PublisherResult = Result<Output,Failure>
func mapToResult() -> AnyPublisher<Result<Self.Output, Self.Failure>, Never>{
self.map{PublisherResult.success($0)}
.catch{Just<PublisherResult>(.failure($0))}
.eraseToAnyPublisher()
}
}
如此一來,就將上游元素轉化為 Result 的 enum
Just(1)
.tryMap{ try willThrow($0)}
.mapToResult()
.sink{ result in
switch result {
case .success(let element): fatalError()
case .failure(let error): print(error)
}
}
extension Publisher {
func applyWhenFailure(receiveError: @escaping (Failure) -> Void) -> Publishers.Catch<Self, Empty<Self.Output, Never>>{
self.catch { error -> Empty<Output, Never> in
receiveError(error)
return Empty<Output,Never>()
}
}
}
以上是目前想到的錯誤處理方法。