Search code examples
swiftcombine

Swift Combine. What is a correct way to return from a block of a timeout handler?


I need to implement a handler for a timeout function in Combine. Let's consider the following code structure:

SomeKindOfPublisher<Bool, Never>()
   .timeout(timeoutInterval, scheduler: backgroundQueue,
      customError: { [weak self] () -> Never in
         ...
         while true {} // This block should not return because of Never
      }

My question is how to avoid a weird line while true {}? I would prefer not to change Never to Error type.


Solution

  • Not sure if this is what you want, but the best way I found to handle timeout on publishers with no failure (Failure == Never) is to force a specific error type and handle timeout error in the completion.

    enum SomeKindOfPublisherError: Error {
        case timeout
    }
    
    publisher
        .setFailureType(to: SomeKindOfPublisherError.self)
        .timeout(.seconds(1), scheduler: backgroundQueue, customError: { .timeout })
        .sink(receiveCompletion: {
            switch $0 {
            case .failure(let error):
                // error is SomeKindOfPublisherError.timeout if timeout error occurs
                print("failure: \(error)")
            case .finished:
                print("finished")
            }
        }, receiveValue: { print($0) })
    

    If think it's strange that the timeout operator doesn't changes the publisher failure type to the custom error on its own, but this is some kind of workaround I found.