RuntimeExceptions are supposed to indicate programming error and I want my application to crash when something inside my observables throws RuntimeException.
What is the best way to do this? Right now I'm considering this solution (it's Kotlin, but I hope it's understandable)
fun <T> Observable<T>.subscribeCrashOnRuntimeException(onNext: (T) -> Unit, onError: (Throwable) -> Unit) {
this.subscribe({
onNext(it)
}, { e ->
if (e is RuntimeException) {
throw e
} else {
onError(e)
}
})
}
fun usageExample() {
val observable = Observable.just(1)
observable.subscribeCrashOnRuntimeExceptions(
{ next -> Log.d("TAG", "next: $next") },
{ e -> Log.d("TAG", "error: $e") }
)
}
But I have doubts about it. For example it is hard to occasionally "catch" specific RuntimeExceptions with this solution. Perhaps there is a well known way to deal with situation that I just don't know how to google?
I don't think there should be much difference in handling runtime (aka unchecked) or regular (aka checked) exceptions. Both are widely used these days and could be either recoverable or not depending on particular situation.
The reactive ways of handling errors are:
onErrorResumeNext
oronErrorReturn
operators; these allow to inspect the error and possibly recover from itretry*
family of operators; these allow to inspect the error and possibly recover from it by means of re-subscribing (for example retry network call)onError
callback of your subscribers; by the way in case you do not supply such a callback the error will be re-thrown in regular Java fashion, so your program will crashRelated topic: How to handle different kinds of errors in Retrofit Rx onError without ugly instanceof
Also note the drawbacks of throwing exceptions in regular Java way:
Sample code
All exceptions get caught by RxJava and passed along the defined route.
onError*
operators act like intermediatecatch
blocks.Subscriber's
onError
callback acts like top-levelcatch
block.More links on the subject: