Recently, I used the RxJava method `Completable.do...
# language-proposals
d
Recently, I used the RxJava method
Completable.doOnEvent
, which takes a lambda `(Throwable?) -> Unit`:
Copy code
myCompletable.doOnEvent { doSomething() }
However, this started throwing exceptions. As it is a Java method, Kotlin automatically regarded
it
as
Throwable!
and therefore
Throwable
, and as soon as the lambda was called with a null value, it did a null check and threw a NPE, even though it was verifying a value that went completely unused. As the only reason Kotlin automatically treats
Throwable!
as
Throwable
here is for convenience, could it recognize in this case that the parameter is entirely unused, and therefore not overeagerly perform a null check? The solution to avoid the exception is to specify
{ _: Throwable? -> doSomething() }
, which I'd rather not need to specify, and I'd especially have preferred not to have to deal with the exception in the first place at all.
k
The
doOnEvent
method is defined to take an argument of
@NonNull Consumer<? super Throwable> onEvent
. Therefore the error is in the caller of `doOnEvent`: it should not pass null to it in the first place. Kotlin rightly treats the lambda as taking a
Throwable
(not
Throwable?
) since it's annotated as
@NonNull
. The platform types (such as
Throwable!
) are only used when there is no annotation and Kotlin then can't determine the nullability of the type.
nono 1
j
That's a nonnull consumer, not a nonnull throwable...
d
Precisely. I even saw the Kotlin interpretation of the argument and it very much specified the argument as
Throwable!
, not
Throwable
, because Rx had no nullability parameter on the
? super Throwable
.
k
You're right - hadn't had enough coffee when I wrote that - it's just a null Consumer. But I still don't understand why it throws an NPE: if it's a
Throwable!
it should allow it to be null (after all, that's what platform types are all about).
d
I throws the NPE because it eagerly does the null check in case the argument is used, my proposal is that it not do that if the argument is proven to be unused.