I've made an extension for Publisher to simplify sink, but my backend (not made by me) is messed up and I have a custom error that shouldn't be an error, and I want to return .success.
extension Publisher {
func sinkToResult(_ result: @escaping ((Result<Self.Output, Self.Failure>) -> Void)) -> AnyCancellable {
return sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
if let error = error as? ApiError, let globalError = error.globalErrors.first, globalError.code == 2233 {
//Here i want to send something like return(.success(true))
}
result(.failure(error))
case .finished:
break
}
},
receiveValue: { output in
result(.success(output))
})
}
}
Can you help me to create a custom Output.Self type that I can return here?
CodePudding user response:
I think you have a couple of options:
enum MyResult<T> {
case noError
case object(T)
}
and then change func signature to:
func sinkToResult(_ result: @escaping ((Result<MyResult<Self.Output>, Self.Failure>) -> Void)) -> AnyCancellable
Or you can wrap Result
and add your specific case:
enum MyResult<Success, Failure: Error> {
case noError
case result(Result<Success, Failure>)
}
and change signature to:
func sinkToResult(_ result: @escaping ((MyResult<Self.Output, Self.Failure>) -> Void)) -> AnyCancellable
.
Either way, I think it would be better to handle this directly when you perform the JSON decoding.
CodePudding user response:
I think what you need is tryCatch
before you get to sink
func tryCatch<P>(_ handler: @escaping (Self.Failure) throws -> P) -> Publishers.TryCatch<Self, P> where P : Publisher, Self.Output == P.Output
Apple docs say:
Handles errors from an upstream publisher by either replacing it with another publisher or throwing a new error.
You could just add it as the last step in your pipeline:
///...
.tryCatch { error in
if let error = error as? ApiError, let globalError = error.globalErrors.first, globalError.code == 2233 {
return Just(true)
} else {
throw error
}
}
It would be difficult to make this generic if you wanted this publisher to return something different depending on circumstances (i.e true
or an empty Array
etc.)