So I have a simple callback class:
class Callback<T>(
val onResponse: (T) -> Unit,
val onError:(Throwable)->Unit
)
Now I want to implement a method that handles errors. There may or may not be an callback
that needs to be invoked.
private fun handleServerError(error:IServerError, callback:Callback<*>? = null){
val reason = error.cause
when(reason){
is Because.ServerRejectsLogin -> {
doAsync { uiThread { mainActivity.longToast("sorry, your session timed out. please log in again.") } }
IntentManager.doLogin(mainActivity)
}
else -> callback?.onError(reason)
}
}
This gets me an error:
Reference has a nullable type
((Throwable) -> Unit)?
use explicit?.invoke()
to make a function-like call, instead
What it seems to expect is
else -> callback?.onError?.invoke(reason)
and I don't quite understand why. Shouldn't the fact that callback
is not null be sufficient to derive that there must be a non-null onError
function?
To add insult to injury, if I write
else -> callback?.let{it.onError(reason)}
then it accepts that but not before warning me that I should
remove redundant
.let
call
The callback?.onError()
syntax would be correct if you were calling a function called onError
on the callback
object with the safe call operator. However, in this case, you are first reading a property of callback
, and then calling another function on what the property returned.
So instead of the expression consisting of just one step, and two pieces:
callback ?.onError()
What you actually have is an expression of three parts, with two operators in a row:
callback ?.onError ()
The last step here, ()
, is a call to the invoke
operator of the object that onError
returns:
callback ?.onError .invoke()
However, since the onError
property is read with a safe call operator, this object might be null
. In this case, you can't use invoke
in its operator form (same goes for any other operator, by the way), so you have to explicitly write it out, with another safe call added:
callback ?.onError ?.invoke()
As for the intention action telling you that you can remove the redundant let
: that's a bug, and should be reported on the issue tracker.