Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set a given Publishers Failure type to Never in Combine

Is there a way to transform a given AnyPublisher<AnyType, SomeError> to AnyPublisher<AnyType, Never>?

like image 696
mike Avatar asked Oct 03 '19 21:10

mike


People also ask

What is a publisher in combine?

Overview. A publisher delivers elements to one or more Subscriber instances. The subscriber's Input and Failure associated types must match the Output and Failure types declared by the publisher. The publisher implements the receive(subscriber:) method to accept a subscriber.

How do you catch errors in combine?

Catching errors If you want to catch errors early and ignore them after you can use the catch operator. This operator allows you to return a default value for if the request failed.

What is PassthroughSubject?

A PassthroughSubject broadcasts elements to downstream subscribers and provides a convenient way to adapt existing imperative code to Combine. As the name suggests, this type of subject only passes through values meaning that it does not capture any state and will drop values if there aren't any subscribers set.


2 Answers

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.

like image 170
matt Avatar answered Oct 16 '22 15:10

matt


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.

like image 17
rraphael Avatar answered Oct 16 '22 17:10

rraphael