거꾸로 바라본 세상
반응형

예외 처리

에러가 발생했을 때 대응하는 방법

1. 소비자(Subscriber/Observer)에게 에러를 통지하기

통지 처리중 에러가 발생하면 소비자에게 에러를 통지해 소비자가 에러에 대응하는 메커니즘을 제공하고, 처리 중 에러가 발생해도 중단을 하기보단 소비자에게 발생한 에러를 통지한다.

subscribe(onNext) 메서드로 구독할 때 에러가 발생해도 stackTrace만 출력할 뿐 별도 에러 처리를하지 않는다. 그러므로 아무런 에러 처리 없이 구독 후 처리 작업을 진행하게되므로 주의가 필요하다.

2. 처리 작업 재시도(retry)

에러가 발생할 경우 생산자의 처리 작업을 처음부터 다시 시도하고, 소비자에게 에러를 통지하진 않는다. 그래서 네트워크가 순간적으로 중단돼 처리 작업이 실패해도 다시 실행하면 성공적인 결과를 얻을 수 있다.

에러가 발생하여 재실행되면 Flowable의 통지 처리를 처음부터 다시시작한다.

[코드]


import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;

public class RetryExm {
    public static void main(String[] args) {
        Flowable<Integer> flowable = Flowable.<Integer>create(emitter -> {
            System.out.println("<<Flowable Start>>");

            for (int i = 1; i <= 3; i++) {
                if (i == 2) { //2이면 에러발생
                    throw new Exception("에러발생");
                }
                emitter.onNext(i); //데이터 통지
            }
            emitter.onComplete(); //완료통지
            System.out.println("처리완료 end");
        }, BackpressureStrategy.BUFFER)
                .doOnSubscribe(subscription -> System.out.println("Flowable : doOnsubscribe"))
                .retry(2) //에러 발생 시 두 번까지 재시도
                .retryUntil(()-> true); //true를 반환하면 재시돌를 하지않고 에러를 통지, false를 반환하면 재시도를 함.

        flowable.subscribe(
                data -> { //onNect();
                    System.out.println("[onNext Data] : "+ data);
                }, error -> { //onError()
                    System.out.println("[onError] : "+ error);
                }, () -> { //onComplete()
                    System.out.println("[onComplete] : End");
                }, subscription -> { //onSubscribe()
                    System.out.println("[onSubscribe]");
                    subscription.request(Long.MAX_VALUE);
                });
    }
}
  • retryUntil() : 재시도를 수행할지 여부를 묻는 메서드로 true이면 재시도를 하지않고 에러를 통지하고, false이면 반환할 때까지 재시도를 수행.
  • retryWhen() : 재시도를를 제어하는 연산자로, 에러가 발생하면 에러 객체를 데이터로 통지하는 Flowable/Observable을 인자로 받아 그 결과를 반환할지, 완료를 통지할지, 에러를 통지할 지 결정한다.

3. 대체 데이터 통지

onError(), onException()으로 시작하는 메서드는 처리 작업을 끝내지 않고 완료하게 하는 에러 처리 방법이 있다. 에러가 발생하면 소비자에게 에러를 통지하지 않고, 대체 데이터나 대체 Flowable/Observable에 있는 데이터를 통지해 처리작업을 실행하고 마지막으로 완료를 통지하여 작업을 성공적으로 종료한다.


import io.reactivex.Flowable;
import io.reactivex.subscribers.DisposableSubscriber;

public class OnErrorEx {
    public static void main(String[] args) throws Exception {
        Flowable<Integer> flowable = Flowable.just(1,3,5,0,2,4)
                .map(data->{
                    int rt = 100 / data;
                    if (rt == 0) {
                        throw new Exception("0이다");
                    }
                    return rt;
                })
                .onErrorReturnItem(-1); //오류가 발생하면 -1을 통지

        flowable.subscribe(new DisposableSubscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                System.out.println("data : " + integer);
            }

            @Override
            public void onError(Throwable t) {
                System.out.println("Error : "+ t);
            }

            @Override
            public void onComplete() {
                System.out.println("Complete");
            }
        });
    }
}

[결과]

data : 100
data : 33
data : 20
data : -1
Complete

에러가 발생할 경우 데이터를 처리하는 메소드

  • onErrorReturnItem(), onErrorReturn() : 오류 발생 시 오류를 통지하지 않고 대체 데이터를 통지해 완료한다.
  • onErrorResumeNext() : 오류 발생 시 오류를 통지하지 않고 Flowable/Observable을 생성하여 데이터를 통지한다. 그리고 인자로 onErrorResumeNext 메서드가 있는데 함수형 인터페이스가 받은 오류 객체에 따라 어떤 통지를 할지 지정할 수 있다.
  • onExceptionResumeNext() : Exception이나 Exception을 상속받는 예외 일 때 Flowable/Observable을 통지하고 그외 는 에러로 통지한다.
반응형
profile

거꾸로 바라본 세상

@란지에。

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!