Is there a way to transform a given AnyPublisher<AnyType, SomeError>
to AnyPublisher<AnyType, Never>
?
2 Answers
A publisher with Never
as error type mean that it can't throw error at all. It will always deliver a value.
To obtain a publisher that can never throw errors you have 2 solutions:
1/ Catch all possible errors:
let publisher: AnyPublisher<AnyType, SomeError> = //...
publisher.catch { error in
// handle the error here. The `catch` operator requires to
// return a "fallback value" as a publisher
return Just(/* ... */) // as an example
}
2/ If you are sure that there no errors can be thrown by the publisher, you can use .assertNoFailure()
, that will convert your publisher. Note that is an error pass through the .assertNoFailure()
, your app will crash immediately.

- 10,041
- 2
- 25
- 33
-
Ah,I didn't know about `assertNoFailure`. Thank you! – mike Oct 04 '19 at 11:49
-
@rraphael It doesn't work, because catch will ( and just too ) completes publisher immediately. There is no generic solution for the author's problem. – gaussblurinc Feb 10 '21 at 13:41
-
I didn't used `catch` for a while now, but I seems to recall that `catch` does complete the publisher (in case it catches an error), but replace the publisher with a new one (here `Just`). So after the `catch` you do have a publisher with `Never` as error type (and you will have the value provided by `Just` in a sink or assign). – rraphael Feb 10 '21 at 13:57
Use the replaceError
operator. This requires that you emit an AnyType value that will be sent down the pipeline from this point if an error arrives from upstream.
For example:
URLSession.shared.dataTaskPublisher(for: url)
.map {$0.data} // *
.replaceError(with: Data()) // *
// ...
From this point on down the pipeline, we are guaranteed that either the Data from the data task completion or (if there is a networking error) an empty Data will be received. The Failure type from this point down the pipeline is Never.

- 515,959
- 87
- 875
- 1,141
-
1I think this is the best answer because it is the most direct and elegant way to achieve what the question is asking for. The accepted answer uses catch which needs to to wrapped in the flatmap if we don't want to end the communication and most of all, this is coming from Matt Neuburg – coffeecoder Dec 16 '21 at 21:16
-
1By the way, just realised replaceError always ends the stream. So catch has more flexibility - you could wrap it in a flatmap to continue the stream – coffeecoder Dec 16 '21 at 21:46