Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error block not called while using ReactiveCocoa

For some reason I am not getting the error message to come through. (I've simplified the code here to get straight to the point.)

// Send an error message 
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendError:error]; // Pretend this is a real error
        return nil;
    }];
}];

// Subscribe to loginButton's returned signal
[_loginButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    [loginSignal subscribeError:^(NSError *error) {
         NSLog(@"A");
    } completed:^{
         NSLog(@"B");
    }];
}];

This prints "B". Any idea why? If -sendError: is called on the subscriber, why does the completion block receive it?

like image 509
drhr Avatar asked Nov 08 '13 00:11

drhr


1 Answers

As you've discovered, RACCommand automatically catches errors within executionSignals.

This is intended to be a convenience for operators like -flatten, -concat, and -switchToLatest, which would otherwise prematurely terminate if an error occurs on any of the inner signals.

If all you care about is knowing when an error occurs, you should use RACCommand.errors instead. If you want to know where the error originated, checking the error domain and code may be easier (or at least more intuitive) than subscribing to the error event of each inner signal.

Subscriptions-within-subscriptions, and even subscriptions in general, are something of a code smell in RAC. Even if you don't want to use errors, there are generally higher-level operators to accomplish what you want (like using -map: to apply a -catch: to each inner signal).

like image 197
Justin Spahr-Summers Avatar answered Sep 25 '22 08:09

Justin Spahr-Summers