[목차]==================================================
1. onError 해주지 않으면 Crash가 발생 주의
2. subscribe 에서 에러 처리
3. Error 캐치 - onErrorReturn
4. Error 캐치 - OnErrorResumeNext
5. Retry
6. Retry 횟수 제한
7. RetryWhen
2. subscribe 에서 에러 처리
3. Error 캐치 - onErrorReturn
4. Error 캐치 - OnErrorResumeNext
5. Retry
6. Retry 횟수 제한
7. RetryWhen
======================================================
RxJava & RxAndroid 사용 시 항상 에러 핸들러를 구독하고 제공하는지 항상 확인해야 합니다. 그렇지 않으면 특히 Scheduler를 적용할 때 스택 트레이스에 아무것도 없을 수 있습니다. 물론 RxJava & RxAndroid 에서 뭔가 잘못됐다고 알려주긴 하지만 어디서 발생했는지 찾을 방법이 없습니다. 항상 에러 콜백을 사용하고, 에러가 발생한다면 에러를 로그로 남겨서 예상치 못한 오류를 기록해야 합니다.
1. onError 해주지 않으면 Crash가 발생 주의
Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> subscriber) throws Exception { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { log("on next: " + s); } }); |
2. subscribe 에서 에러 처리
Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> subscriber) throws Exception { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); } }).subscribe(new DefaultObserver<String>() { @Override public void onNext(String value) { log("on next: " + value); } @Override public void onError(Throwable e) { // 에러시 처리를 여기로 받음 log("error:" + e); } @Override public void onComplete() { log("completed"); } }); |
[출력결과] subscribe on next: emit 1 on next: emit 2 error:java.lang.Throwable |
3. Error 캐치 - onErrorReturn
Observable 체인 안에서 발생한 Error 를 캐치해서, 대체할 Object로 변환하는 것으로 subscriber에 Error가 전달되는 것을 막을 수 있다.
Observable 체인 안에서 발생한 Error 를 캐치해서, 대체할 Object로 변환하는 것으로 subscriber에 Error가 전달되는 것을 막을 수 있다.
Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> subscriber) throws Exception { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); } }).onErrorReturn(new Function<Throwable, String>() { @Override public String apply(Throwable throwable) throws Exception { return "return"; } }).subscribe(new DefaultObserver<String>() { @Override public void onNext(String value) { log("on next: " + value); } @Override public void onError(Throwable e) { // 에러시 처리를 여기로 받음 log("error:" + e); } @Override public void onComplete() { log("completed"); } }); |
[출력결과] subscribe on next: emit 1 on next: emit 2 on next: return completed |
4. Error 캐치 - OnErrorResumeNext
Observable 체인에서 발생한 Error를 캐치해서, 그 안에서 다시 한 번 Observable를 호출하면 에러시 대체 Stream을 반환할 수 있다.
Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> subscriber) throws Exception { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); } }).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends String>>() { @Override public ObservableSource<? extends String> apply(Throwable throwable) throws Exception { return Observable.fromArray(new String[]{"resume 1", "resume 2"}); } }).subscribe(new DefaultObserver<String>() { @Override public void onNext(String value) { log("on next: " + value); } @Override public void onError(Throwable e) { // 에러시 처리를 여기로 받음 log("error:" + e); } @Override public void onComplete() { log("completed"); } }); |
[출력결과] subscribe on next: emit 1 on next: emit 2 on next: resume 1 on next: resume 2 completed |
5. Retry
Error가 일어났을 때, 자동으로 subscribe를 다시 해준다.
Error가 일어났을 때, 자동으로 subscribe를 다시 해준다.
성공할때까지 계속... 무한루프 될 가능성이 있으므로 유의해야 한다
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }) .retry() .subscribe() |
[출력결과] subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 . . . 반복 |
6. Retry 횟수 제한
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }) .retry(3) .subscribe() |
[출력결과] subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 error:java.lang.Throwable |
Retry 좀 더 구체적인 설정
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }) .retry(new BiPredicate<Integer, Throwable>() { @Override public boolean test(Integer integer, Throwable throwable) throws Exception { if (integer < 3) { return true; } return throwable instanceof IllegalStateException; } }) .subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
[출력결과] subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 error:java.lang.Throwable |
7. RetryWhen
보다 세밀하게 retry 처리를 제어하기 위한 함수.
보다 세밀하게 retry 처리를 제어하기 위한 함수.
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() { @Override public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception { return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() { @Override public ObservableSource<?> apply(Throwable throwable) throws Exception { return Observable.timer(3, TimeUnit.SECONDS); } }); } }).subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
[출력결과] subscribe on next: emit 1 on next: emit 2 // 3초 후 subscribe on next: emit 1 on next: emit 2 // 3초 후 subscribe on next: emit 1 on next: emit 2 . . . 반복 |
그냥 Error인채로 종료
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }).subscribeOn(AndroidSchedulers.mainThread()) .retryWhen(throwableObservable -> throwableObservable.flatMap( throwable -> Observable.error(throwable) )).subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }).onErrorResumeNext(throwable -> {Observable.empty();}) .subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
[출력결과] subscribe on next: emit 1 on next: emit 2 completed |
3번 retry하고 종료
이 경우, 앞의 retry(count) 함수와의 차이는 retry(count)에서는 retry 횟수가 제한에 도달한 후에 error로 종료합니다만, 이 케이스는 completed 에서 종료한다는 점이다.
이 경우, 앞의 retry(count) 함수와의 차이는 retry(count)에서는 retry 횟수가 제한에 도달한 후에 error로 종료합니다만, 이 케이스는 completed 에서 종료한다는 점이다.
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }).retryWhen(throwableObservable -> throwableObservable.take(3)) .subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
[출력결과] subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 subscribe on next: emit 1 on next: emit 2 completed |
3초 retry를 3번 하고 종료하기
Observable.create(subscriber -> { log("subscribe"); subscriber.onNext("emit 1"); subscriber.onNext("emit 2"); subscriber.onError(new Throwable()); }).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() { @Override public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception { return throwableObservable.take(3).flatMap(new Function<Throwable, ObservableSource<?>>() { @Override public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception { return Observable.timer(3, TimeUnit.SECONDS); } }); } }).subscribe(s -> log("on next: " + s) , e -> log("error:" + e) , () -> log("completed")); |
[출력결과] subscribe on next: emit 1 on next: emit 2 // 3초 후 subscribe on next: emit 1 on next: emit 2 // 3초 후 subscribe on next: emit 1 on next: emit 2 completed |
출처 : 인터넷에서 RxAndroid 검색하여 필요한 정보를 다양한 사이트에서 종합하여 작성된 것입니다. 많은 사이트 내용을 종합하여 공부하여 작성하다보니 일일이 나열하지 못하였습니다. ㅈㅅ(_ _) 이글은 자유롭게 퍼 가셔서 도움이 되었으면 좋겠습니다. 감사합니다.
댓글 없음:
댓글 쓰기