title: Swift Combine: turn error into the publisher's output
body: <p>I am trying to refactor some code where I am currently mixing a Combine publisher with a callback closure.</p>
  
  <p>The code does a login request to a REST endpoint. On failure, I want the caller of the function to receive the error payload (a challenge), on success, the caller doesn't need to do anything. So it's a bit of a weird situation where the caller is ONLY interested in the error.</p>
  
  <p>Currently I am doing it like this (simplified code):</p>
  
  <pre class="lang-swift prettyprint-override"><code>import Foundation
  import Combine
  
  struct Challenge {
    let id: Int
  }
  
  struct MyError: Error {
    let challenge: Challenge?
  }
  
  class UserManager {
    @Published var user: String?
  
    private func doRequest(username: String, password: String) -&gt; AnyPublisher&lt;String, MyError&gt; {
      // In the real world this does a request to a REST API, returning either a User object or an error containing a Challenge.
      return Fail(outputType: String.self, failure: MyError(challenge: Challenge(id: 1)))
        .eraseToAnyPublisher()
    }
  
    func login(username: String, password: String, next: @escaping (Challenge) -&gt; ()) -&gt; AnyCancellable {
      doRequest(username: username, password: password)
        .catch { error -&gt; AnyPublisher&lt;String, Never&gt; in
          if let challenge = error.challenge {
            next(challenge)
          }
          return Empty().eraseToAnyPublisher()
        }
        .sink(
          receiveValue: { [weak self] user in
            self?.user = user
          }
        )
    }
  }
  
  let userManager = UserManager()
  var anyCancellables = Set&lt;AnyCancellable&gt;()
  
  userManager.login(username: "hello", password: "world") { challenge in
    print("received challenge!")
  }
  .store(in: &amp;anyCancellables)
  </code></pre>
  
  <p>As you can see, the <code>login</code> function takes a parameter called <code>next</code>, and the publisher itself handles the value inside the <code>sink</code> operator. It doesn't feel good to combine a publisher with a closure like this, ideally I'd like the <code>login</code> function to have this signature:</p>
  
  <pre class="lang-swift prettyprint-override"><code>func login(username: String, password: String) -&gt; AnyPublisher&lt;Challenge, Never&gt;
  </code></pre>
  
  <p>But when I want to write such a function I am running into the problem where I can't use a <code>sink</code> within the <code>login</code> function itself, since that transforms the return type into a <code>AnyCancellable</code>. Basically I want to turn the error into the publisher's output, and also handle the actual value inside the <code>login</code> function. How is this possible?</p>