onErrorReturn()
에러도 하나의 데이터이기 때문에 예외 발생 시 에러를 의미하는 다른 데이터로 변환 후에 데이터(에러)를 발행해야 한다.
fun main() = runBlocking<Unit> {
val numbers = listOf("1", "2", "$3", "4", "5")
Observable.fromIterable(numbers)
.map { Integer.parseInt(it) }
.onErrorReturn { error ->
if (error is NumberFormatException) {
error.printStackTrace()
}
return@onErrorReturn -1 // 에러를 의미하는 -1 전달
}
.subscribe { item ->
if (item < 0) {
println("Error")
} else {
println("item is $item")
}
}
delay(1000)
}
// item is 1
// item is 2
// Error
// java.lang.NumberFormatException: For input string: "$3"
onErrorReturnItem()
onErrorItem()
과 동일하지만 중간에 에러를 넘기는 부분에 대한 구현을 생략할 수 있는 함수이다.
fun main() = runBlocking<Unit> {
val numbers = listOf("1", "2", "$3", "4", "5")
Observable.fromIterable(numbers)
.map { Integer.parseInt(it) }
.onErrorReturnItem(-1)
.subscribe { item ->
if (item < 0) {
println("Error")
} else {
println("item is $item")
}
}
delay(1000)
}
// item is 1
// item is 2
// Error
onErrorResumeNext()
에러 발생 시 다른 Observable
로 대체하여 전달하는 함수이다.
fun main() = runBlocking<Unit> {
val numbers = listOf("1", "2", "3", "4", "5")
val onParseError = Observable.defer {
println("Change Observable")
Observable.just(-1)
}.subscribeOn(Schedulers.io())
Observable.fromIterable(numbers)
.map { Integer.parseInt(it) }
.onErrorResumeNext(onParseError)
.subscribe { item ->
if (item < 0) {
println("Error")
} else {
println("item is $item")
}
}
delay(1000)
}
// item is 1
// item is 2
// Change Observable
// Error
retry()
에러 발생 시 재시도하는 함수로, 반복할 횟수를 지정할 수 있으며 true
를 반환하면 재시도, false
를 반환하면 중단한다.
fun main() = runBlocking {
val stream = Observable.range(1, 10)
.map {
if (it == 3) {
throw Exception("Error")
} else {
it
}
}
println("retry() start")
stream.retry(2)
.subscribeBy(
onNext = { println("onNext() - $it") },
onError = { println("onError() - ${it.message}") }
)
println("\nretry lambda start")
stream.retry { retryCount, e ->
println("retry count : $retryCount")
if (retryCount > 2) {
false
} else {
true
}
}.subscribeBy(
onNext = { println("onNext() - $it") },
onError = { println("onError() - ${it.message}") }
)
}
// retry(2) start
// onNext() - 1
// onNext() - 2
// onNext() - 1
// onNext() - 2
// onNext() - 1
// onNext() - 2
// onError() - Error
// retry lambda start
// onNext() - 1
// onNext() - 2
// retry count: 1
// onNext() - 1
// onNext() - 2
// retry count: 2
// onNext() - 1
// onNext() - 2
// retry count: 3
// onError() - Error
retryUntil()
에러 발생 시 설정한 조건이 만족할 때까지 재시도하는 함수이다.
fun main() = runBlocking<Unit> {
val stream = Observable.range(1, 10)
.map {
if (it == 3) {
throw Exception("Error")
} else {
it
}
}
var retryCount = 0
stream.retryUntil {
if (retryCount == 3) {
true
} else {
retryCount++
println("Retry - ${retryCount}\n")
false
}
}.subscribeBy(
onNext = { println("onNext() - $it") },
onError = { println("onError() - ${it.message}") }
)
}
// onNext() - 1
// onNext() - 2
// Retry - 1
// onNext() - 1
// onNext() - 2
// Retry - 2
// onNext() - 1
// onNext() - 2
// Retry - 3
// onNext() - 1
// onNext() - 2
// onError() - Error