RxErrorHandling

请勿在生产环境中使用

目前这只是一个概念验证,尚未经过实战测试,也未为生产环境做好准备。

是什么

RxErrorHandling 为 RxSwift 引入了 Treatable 特性。这些特性具有类似于 Combine 的错误处理机制,Rx 序列的错误类型是签名的一部分,并强制执行错误处理。

我非常清楚这个名字很奇怪,欢迎任何关于更好名称的建议。

简而言之的用法

创建 Treatables

使用 create 函数(类似于 SingleObservable)来创建 Treatable,或者使用 asTreatable 将任何 ObservableType 转换为 Treatable

enum FooError: Error {
    case foo
    case otherFoo
}

enum BarError: Error {
    case bar
    case otherBar
}

// Use create function
let foo = Treatable<String, FooError>.create { treatable in
    guard precondition else {
        treatable(.completed(.failure(.foo)))
        return
    }

    while whatever {
        guard otherPrecondition else {
            treatable(.completed(.failure(.otherFoo)))
            return
        }
        
        treatable(.next(nextValue))
    }
    treatable(.completed(.finished))
}

// Or asTreatable with error mapping (here: someObservable: Observable<String>)
let bar = someObservable.asTreatable(mapError: { error in
    error as? BarError ?? .otherBar
})

映射和组合

使用 Observable、Single、Signal 等的所有已知函数,并另外使用 mapError 来映射或统一错误类型。

enum CombinedError: Error {
    case foo
    case bar
    case other
}

// Map error types to match, when combining sequences
let merged = Treatable<String, CombinedError>.merge(
    foo.mapError { fooError in 
        switch fooError {
            case .foo: return .foo
            case .otherFoo: return .other
        }
    },
    bar.mapError { barError in 
        switch barError {
            case .bar: return .bar
            case .otherBar: return .other
        }
    }
)

或者映射回 observable,以便与现有库兼容,例如。

let someTreat: Treatable<Success, Failure>
let infallibleObservable: Observable<Result<Success, Failure>> = someTreat.asResultObservable()
let fallibleObservable: Observable<Success> = someTreat.asObservable()

结果处理

使用 treat 函数来处理结果

// Use treat function to handle results
merged.treat(onNext: { value in
    // handle next value
}, onCompleted: { completion in
    switch completion {
    case .failure(.foo): break // handle error
    case .failure(.bar): break // handle error
    case .failure(.other): break // handle error
    case .finished: break // handle success
    }
})

let noErrors: Treatable<Element, Never>
noErrors.treat(myObserver) // just use any ObserverType

let mayHaveErrors: Treatable<Result<Success, Failure>, Failure>
mayHaveErrors.treat(myObserver) // use any ObserverType with Element == Result<Success, Failure>

可用的 Treatable 特性