This is a tricky question because your desired error handling is fundamentally incompatible with the RACSignal API RACSignal , which states that errors have exception semantics .
The only way to ignore, but still take care of the errors, is to redirect them to another place. In this example, I will use the theme:
RACSubject *remoteErrors = [RACSubject subject];
... but you can also use a property or some other notification mechanism.
I will continue to use the remoteSignal and cacheSignal tags that you specified above, with some changes. Here is the behavior we want from them:
remoteSignal should send its errors to remoteErrorscacheSignal should be discarded as soon as remoteSignal sends the value- Errors from any signal should not interrupt another
- We want to combine the values ββfrom
cacheSignal and remoteSignal so that we still get the remote value after reading the cache.
With that in mind, take a look at remoteSignal :
RACSignal *remoteSignal = [[[[[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestUseProtocolCachePolicy] doError:^(NSError *error) { [remoteErrors sendNext:error]; }] finally:^{
-doError: and -finally: manage the remoteErrors theme, fulfilling our first requirement above. Since we need to use remoteSignal in more than one place (as you can see in the list above), we use -replayLazily to make sure that its side effects occur only once.
cacheSignal almost unchanged. We just need to use -takeUntil: to ensure that it exits when remoteSignal sends a value (but does not send an error):
RACSignal *cacheSignal = [[[IssueWSRequest instance] issueWithId:issueId cachePolicy:NSURLRequestReturnCacheDataDontLoad] takeUntil:remoteSignal];
Finally, we want to combine their values, so that both signals are triggered simultaneously and their values ββcan come in any order:
return [RACSignal merge:@[ [cacheSignal catchTo:[RACSignal empty]], [remoteSignal catchTo:[RACSignal empty]] ];
We ignore errors here because the error either stops both (since they are now merged). Error handling behavior has already been described above.
And despite the merge, using -takeUntil: in cacheSignal ensures that the value cannot be sent after remoteSignal .
Once again looking at the list of requirements, you can see the operators used to execute each of them:
[-doError:] remoteSignal should send its errors to remoteErrors[-takeUntil:] cacheSignal should be canceled as soon as remoteSignal sends the value[-catchTo:] Errors from any signal should not interrupt another[+merge:] We want to combine the values ββfrom cacheSignal and remoteSignal so that we still get the remote value after reading the cache.