title: RAC 4 Swift Failed method
body: <p>ReactiveCocoa 4 has a method on the <code>SignalProducer</code> class, <code>then</code> that waits for the producer to completed and replaces it with another producer like so:</p>
  
  <p><code>someProducer.then(replacementProducer)</code>.</p>
  
  <p>However what I want is a method that waits until the original producer errors out and then replaces it with the second producer (doing nothing on completion events).</p>
  
  <p><code>then</code> is implemented as (note next events are not forwarded):</p>
  
  <pre><code>public func then&lt;U&gt;(replacement: SignalProducer&lt;U, Error&gt;) -&gt; SignalProducer&lt;U, Error&gt; {
      let relay = SignalProducer&lt;U, Error&gt; { observer, observerDisposable in
          self.startWithSignal { signal, signalDisposable in
              observerDisposable.addDisposable(signalDisposable)
  
              signal.observe { event in
                  switch event {
                  case let .Failed(error):
                      observer.sendFailed(error)
                  case .Completed:
                      observer.sendCompleted()
                  case .Interrupted:
                      observer.sendInterrupted()
                  case .Next:
                      break
                  }
              }
          }
      }
      return relay.concat(replacement)
  }
  </code></pre>
  
  <p>What I want would look similar except on failure, instead of sending an error, it would send a completed signal. More specifically the switch statement would change to look like:</p>
  
  <pre><code>signal.observe { event in
      switch event {
          case .Failed:
              observer.sendCompleted()
          case .Completed, .Next: break
          case .Interrupted:
              observer.sendInterrupted()
          }
      }
  }
  </code></pre>
  
  <p>My questions are as follows:</p>
  
  <p>1) Is this valid? It works as I would expect, the replacement signal is only started when the first signal errors out.
  2) Is there a better way to do it so that the error information doesn't get lost?</p>
  
  <p>An example of where I would use this is a two-step authentication process:</p>
  
  <p><code>self.verifyToken(token).failed(self.revalidateSession())</code></p>
  
  <p>If the token verification succeeds, all is good and no need to revalidate. If it fails, then revalidation needs to occur.</p>
  
  <p>EDIT:</p>
  
  <p>I changed the signal observation block so that if the first signal completes with no error, it starts the replacement signal with <code>startWithComplete</code> so that completion events are forwarded down the chain without triggering any action from the signal.</p>
  
  <p>That makes it easy to do this:</p>
  
  <p><code>self.verify(token).failed(self.refreshSession(token)).then(self.fetchUserForToken(token))</code></p>
  
  <p>where <code>then</code> is chained and only gets executed when either <code>verify</code> or <code>refreshSession</code> is successful.</p>
  
  <pre><code>signal.observe { event in
      switch event {
          case .Failed:
              observer.sendCompleted()
          case .Completed:
              replacement.startWithCompleted {}
          case .Next: break
          case .Interrupted:
              observer.sendInterrupted()
          }
      }
  }
  </code></pre>