🔔 앞으로의 Reactive X 시리즈는 RxJava, RxKotlin 기준으로 작성됩니다
공식 문서를 참고하여 작성된 포스팅입니다.
이전 포스팅과 이어집니다.
데이터가 발행되다보면, 은연중에 오류가 발생할 수도 있는 것이다. 그런데 보통 데이터 스트림에서 오류가 발생하면, 즉시 데이터 스트림이 종료되기 때문에 따로 조치를 해주어야 하는 상황이 있을 수 있다. 이번 포스팅에선 Observable 에서 발생할 수 있는 에러를 핸들링하는 방법 몇 가지를 알아보자.
이전에 Observable 에서 에러가 발생하면 Emitter.onError()
이벤트를 발행하는 것을 배운 적 있다. subscribe()
안에 onNext()
Consumer 뿐만 아니라 onError()
Consumer 를 넣어줌으로써, onError()
를 구독할 수 있다. 가장 일반적인 에러 핸들링 기법이다.
fun main() {
Observable.just("1", "2", "A", "3")
.map { it.toInt() }
.subscribe(System.out::println) {
println(it) // onError() Consumer
}
}
1
2
java.lang.NumberFormatException: For input string: "A"
map()
함수에서 문자열을 정수형으로 바꾸는 동작을 하고 있는데, A
를 만난 순간 오류가 발생할 것이다. 이 때 발행된 onError()
를 출력하는 구문을 subscribe()
에 넣어줬더니, 정상적으로 출력된 것을 확인할 수 있다. 물론 에러가 발생한 이후 데이터는 더 이상 발행되지 않는다.
이것은 Consumer 를 넘겨줌으로써 구현한 에러 핸들링인데, 이외에 오류 처리 전용 연산자를 활용하는 방법들도 있다. 아래를 살펴보자.
이 녀석은 에러가 발생했을 때, onError()
이벤트 발생 대신 오류 처리를 위한 구문을 담은 함수를 실행한다.
fun main() {
Observable.just("1", "2", "A", "3")
.map { it.toInt() }
.onErrorReturn { -1 }
.subscribe { x: Int? -> println(x) }
}
1
2
-1
물론 오류가 발생한 순간부터 데이터 스트림은 멈춘다.
만약 에러가 발생한다면, 해당 데이터 스트림을 종료하고 기입해준 다른 Observable 로 데이터 스트림을 교체하여 데이터를 발행하게 된다.
fun main() {
Observable.just("1", "2", "A", "3")
.map { it.toInt() }
.onErrorResumeNext(Observable.just(10, 20, 30))
.subscribe(System.out::println)
}
1
2
10
20
30
A
를 발행하다 오류가 발생하여, 새로운 Observable 의 데이터 10부터 차례대로 발행되는 것을 확인할 수 있다. 매우 직관적인 메소드명이다.
다시 시도.. 말 그대로 데이터 발행을 재시도하게 하는 녀석이다. 에러가 발생할 경우, 다시 해당 Observable 을 구독한다. (재구독) 하지만 무한 루프에 빠질 가능성이 있기 때문에, 횟수를 지정해주게 된다. (Long 타입)
fun main() {
Observable.just("1", "2", "A", "3")
.map { it.toInt() }
.retry(3)
.onErrorReturn { -1 }
.subscribe(System.out::println)
}
1
2
1
2
1
2
1
2
-1
이번 포스팅에선 Observable 데이터 스트림에서 발생할 수 있는 오류를 핸들링하는 방법들에 대하여 알아보았다.
벨로그 글을 읽다보면요. 이상하게 너무 잘 읽히고, 안드로이드 개발자 입장에서 이해하기 쉽게 잘 설명돼 있다는 생각이 들 때가 있습니다. 그럴 때마다 스크롤을 마저 내려보면 꼭 해로님 글이더라구요. 오늘도 많은 도움 받았습니다.