Reputation: 148021
I'm trying to write my own extension function for RxKotlin which would make an Observable
handle a specific error type (Throwable
subclass) with a handler which is passed as an argument and emit no more items.
Marble diagram would be:
--- a --- b --- c --- error : T
[ handleError<T>(handler) ]
--- a --- b --- c --- finished
|
handler(error)
I wrote the following:
public inline fun <reified E : Throwable, R> Observable<R>.handleError(
crossinline handler: (E) -> Unit
) = onErrorResumeNext f@{
return@f when (e) {
is E -> { handler(e); Observable.empty() }
else -> Observable.error(e)
}
}
It's working OK, but to use it I have to write, for example:
val myObservable: Observable<SomeClass> = ...
myObservable.handleError<IOException, SomeClass> { it.printStackTrace() }
^^^^^^^^^
I don't like it that I have to write the Observable
's generic in handleError
call, I'd like to avoid it.
So, is there a way to avoid explicitly specifying the second generic parameter?
I suppose, there's no way to make the compiler infer it once I specify one of generic parameters. But is there any way to rewrite handleErrors
to achieve what I want?
Upvotes: 3
Views: 448
Reputation: 43841
First, to specify E
explictly, you could use the more verbose lambda syntax. This would look like this:
myObservable.handleError { it : IOException -> it.printStackTrace() }
Alternativly, you could add an additional parameter to help the compiler infer the type. This could look something like this:
public inline fun <reified E : Throwable, R> Observable<R>.handleError(
typeHint: (E) -> Unit,
crossinline handler: (E) -> Unit
) = onErrorResumeNext f@{
return@f when (e) {
is E -> { handler(e); Observable.empty() }
else -> Observable.error(e)
}
}
fun <T> of() : (T) -> Unit = {}
Usage:
myObservable.handleError(of<IOException>()) { it.printStackTrace() }
Upvotes: 7