Is Deferred<Unit> supported?
Closed this issue ยท 16 comments
I recall a snippet of a UnitConverterFactory
you posted in an issue. Is is needed to support Deferred<Unit>
for 204 No Content or ignored body responses?
Yes. This is only a call adapter. If you want a converter for Unit
as a body type, you'll need to install one separately.
@JakeWharton Could be nice to post the snippet in the README since it's likely to be needed by users of this library
I don't understand why this is not provided out of the box. Or am I misunderstanding something?
When I have a POST
or PATCH
isn't Deferred<Unit>
always what I want to return here?
When using retrofit directly I use a Call<Void>
This is an adapter which provides you Deferred<T>
. If you want to use Unit
for T
, you want a converter.
And how is that possible? I try to write a moshi adapter like
class UnitJsonAdapter {
@FromJson
fun fromJson(value: String?): Unit = Unit
@ToJson
fun toJson(unit: Unit): String? = null
}
But it fails because the fromJson uses void
in bytecode.
Thanks! Also I ask myself if there is no better representation for that. Like RxJava has Completable
. Maybe just allow returning a plain Job
?
With that Unit call adapter I have exceptions for Deferred<Unit>
(which are printed to std?)
W/System.err: kotlin.KotlinNullPointerException
W/System.err: at com.jakewharton.retrofit2.adapter.kotlin.coroutines.experimental.CoroutineCallAdapterFactory$BodyCallAdapter$adapt$2.onResponse(CoroutineCallAdapterFactory.kt:102)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:123)
W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
W/System.err: at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
W/System.err: at java.lang.Thread.run(Thread.java:764)
@PaulWoitaschek Try adding the UnitConverterFactory
before other converter factories when you configure your Retrofit.
I'm getting the same error @PaulWoitaschek, how did you fix it?
@LouisCAD, it is currently the first one on the list.
I'm just confused if I even still need the call adapter.
I fixed this by checking for the Unit type:
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
if (responseType == Unit::class.java) {
@Suppress("UNCHECKED_CAST")
deferred.complete(Unit as T)
} else {
deferred.complete(response.body()!!)
}
} else {
deferred.completeExceptionally(HttpException(response))
}
}
@JakeWharton Will you accept a PR on this?
I'm getting the same error output as @PaulWoitaschek, with Retrofit 2.5.0, and including UnitConverterFactory
before any others, using Deferred<Response<Unit>>
alleviates it.
Is this still an issue? or is it just an incorrect configuration?
Also it would help debugging to write to Log.e
instead of Log.w
I'm getting the same error, with build in UnitResponseBodyConverter in Retrofit 2.6.0. I used @PaulWoitaschek fix on response function.