2017-08-17 1 views
1

J'ai deux sources de Singles, que je combine en un Single of Pair.Comment retourner Single.error() lorsque l'une des sources dans Single.zip échoue?

Disons que nous avons deux méthodes pour ces sources:

private Single<String> single1() {} 
private Single<String> single2() {} 

Maintenant, je les combine dans Single<Pair<String, String>

private Single<Pair<String, String> combineSingles() { 
    Single.zip(single1(), single2(), BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2)) 
} 

Lorsque l'une des méthodes (single1 ou single2) retourne Single.error() , Je reçois UndeliverableException parce que l'erreur n'est pas gérée dans l'opérateur zip. Je veux plutôt retourner Single.error() de combineSingles() méthode, comment puis-je y parvenir?

+0

Quelle est la stacktrace exacte de ce 'UndeliverableException'? – akarnokd

Répondre

3

essayer cette

private Single<Pair<String, String> combineSingles() { 
    try { 
     Single.zip(single1(), single2(), BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2)) 
    } catch (Exception e) { 
     Single.error() 
    } 
} 

par la façon dont je premier à suggérer la méthode de capture try :)

+0

Ok, ça a l'air bien, mais est-ce la meilleure solution à coup sûr? – ThirdMartian

+0

il va attraper toutes les erreurs lancées, et c'est à vous de les gérer comme vous le souhaitez, vous pourriez essayer d'attraper plusieurs exceptions avec cette méthode. –

0

Que diriez-vous de la logique try/catch habituelle?

Single<String> single1; 
try { 
    single1 = single1(); 
} catch (RuntimeException e) { 
    return Single.error(); 
} 
Single<String> single2; 
try { 
    single2 = single2(); 
} catch (RuntimeException e) { 
    return Single.error(); 
} 
return Single.zip(single1, single2, BiFunction<String, String, Pair<String, String>>) (t1, t2) -> new Pair(t1, t2)) 

Ou si vous voulez remplacer la valeur défectueuse par Single.error(), puis

Single<String> single1; 
try { 
    single1 = single1(); 
} catch (RuntimeException e) { 
    single1 = Single.error(); 
} 

Et ainsi de suite.

+0

Je ne pense pas que vous compreniez mon problème, je pense que le code va planter pour la même raison, car je n'ai pas géré l'erreur dans l'opérateur zip – ThirdMartian

+0

@ThirdMartian Eh bien, vous avez dit que l'une des * méthodes * 'single1()'/'single2()' peut échouer. Dans mon code, leurs invocations sont enveloppées avec try/catch. Si une autre exception survient dans la méthode 'zip()', elle ne sera pas gérée, c'est vrai. –

+0

Oui, ma faute, je vais éditer ma question pour mieux l'expliquer. – ThirdMartian

0

onErrorResumeNext(...) est votre ami, qui est l'équivalent try/catch pour RxJava.

Voici l'exemple complet

public final class RxTest { 

    private static Single<String> single1() { 
     return Single.just("1"); 
    } 
    private static Single<String> single2() { 
     return Single.error(new RuntimeException("single2")); 
    } 

    private static Single<Pair<String, String>> combineSingles() { 
     return Single.zip(single1(), single2(), Pair::new) 
       .onErrorResumeNext(Single.error(new RuntimeException("zip"))); 
    } 

    public static void main(String[] args) { 
     combineSingles() 
       .test() 
       .assertError(RuntimeException.class) 
       .assertError(throwable -> "zip".equals(throwable.getMessage())); 
    } 
}