Reactive Programming with RxJava-Chapter7:Test and Troubleshooting(1)

Error Handling

The Reactive Manifesto enumerates four traits that reactive systems should embrace
- responsive
- resilient
- elastic
- message driven

Where Are My Exceptions

In RxJava,failures are just another type of notification.Every Observable is a sequence of events of type T optionally followed by completion or error notification.

Subscribe() only listening for values and not errors is often a bad sign and possibly missed errors.Even if you do not except any exceptions to happen (which is rarely the case),at least place error logging that plugs into your logging framework.

It is advised to explicitly propagate exceptions via subscriber.onError() if possible.Even better,use fromCallable()

Declarative try-catch Replacement

Replacing errors with a fixed result using onErrorReturn()

onErrorReturn() is a fluent and very pleasant to read alternative to a try-catch block that returns fixed result in the catch statement know from imperative style;

Lazily computing fallback value using onErrorResumeNext()

There are two possible scenarios here:
- The primary way of generating a stream of data failed (onError() event,so we switch to a secondaty source that is just as good,but for some reason we treate it as backup)
- In the presence of a failure,we would like to replace real data with some less expensive,more stable,maybe stale information.

The onErrorResumeNext() operator basically replaces error notification with another stream.If you subscribe to an Observable guarded with onErrorResumeNext() in case of failure,RxJava transparently switches from main Observable to the fallback one,specified as an argument.

Timing out When Events Do Not Occur

simplest use case for timeout():timeout(long,TimeUnit)
timeout(long,TimeUnit)

This is quite common in real-life systems: the initial element of the response has relatively high latency as a result of establishing the connection,SSL handshake,query optimization,or whatever the server is doing.But subsequent responses are either readily available or easily retrievable,so latency between them is much lower;
timeout(Func0,Func1)

Similar in behavior to onErrorResumeNext();
timeout(long,TimeUnit,Observable)

Retrying After Failures

The onError notification is terminal;no other event can ever appear in such stream.

Attention
If your Observable is cached or otherwise guaranteed to always return the same sequence of elements,retry() will not work:

    risky().cached().retry()  //BROKEN

To overcome this issue,you can delay the creation of Observable even futher by using defer()

    Observable
        .defer(() -> risky())
        .retry()

Retrying by using delay and limited attempts

retryWhen(Func1)
retryWhen(Func1)

Attention
The retryWhen operator is similar to retry but decides whether or not to resubscribe to and mirror the source Observable by passing the Throwable from the onError notification to a function that generates a second Observable, and observes its result to determine what to do. If that result is an emitted item, retryWhen resubscribes to and mirrors the source and the process repeats; if that result is an onError notification, retryWhen passes this notification on to its observers and terminates.

Observable.create((Subscriber<? super String> s) -> {
      System.out.println("subscribing");
      s.onError(new RuntimeException("always fails"));
  }).retryWhen(attempts -> {
      return attempts.zipWith(Observable.range(1, 3), (n, i) -> i).flatMap(i -> {
          System.out.println("delay retry by " + i + " second(s)");
          return Observable.timer(i, TimeUnit.SECONDS);
      });
  }).toBlocking().forEach(System.out::println);

result:

subscribing
delay retry by 1 second(s)
subscribing
delay retry by 2 second(s)
subscribing
delay retry by 3 second(s)
subscribing

Another example:

static final int ATTEMPTS = 11;

//...

.retryWhen(attempts -> attempts
        .zipWith(Observable.range(1,ATTEMPTS) , (err,attempt) ->
                attempt < ATTEMPTS ?
                        Observable.timer(1,SECONDS) :
                        Observable.error(err))
        .flatMap(x -> x)
)

最后,安利一款自己写的基于MVP的Android开发框架
https://github.com/sxenon/Pure
欢迎大家拍砖,如果觉得好,麻烦多多star

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值