I'm using Retrofit 2.7.1 with Kotlin coroutines.
I have a Retrofit service defined as such:
@PUT("/users/{userId}.json")
suspend fun updateUserProfile(
@Path("userId") userId: String,
@Query("display_name") displayName: String) : Void
This call returns an HTTP 204 No Content response, which causes a crash in Retrofit:
kotlin.KotlinNullPointerException: Response from com.philsoft.test.api.UserApiService.updateUserProfile was null but response body type was declared as non-null
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:43)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:129)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
How do I handle a 204 response in retrofit, using coroutines, without crashing?
According to this, use Response<Unit>
in the retrofit method declaration.
retrofit no content issue
You can use Response<Unit>
to handle 204 responses using Retrofit
but when you handle like this Retrofit
will not throw an exception for 4xx
responses or other exceptional cases.
You may deal with these cases with the following code:
return try {
val result = apiCall.invoke()
return if (result is Response<*>) {
if (result.code() >= 400) {
// create an error from error body and return
} else {
// return success result
}
} else {
// directly return success result
}
} catch (t: Throwable) {
// create an error from throwable and return it!
}
Explaining answer of @Dmitri with the sample code:
In your APIInterface, call your API like this,
@GET(AppConstants.APIEndPoints.GET_NEWS)
suspend fun getNews(
@Query("limit") limit: String,
): Response<NewsListResponseModel>
where, Response is retrofit2.Response
From where you call the API, check for the status code from the function like apiResponse.code()
.
val apiResponse = apiEndPointsInterface.getNews(limit)
if (apiResponse.code() == HttpURLConnection.HTTP_OK) {
//response success
ResultOf.Success(apiResponse.body()!!))
} else {
//handle your other response codes here
ResultOf.Failure("No Data Found.", null))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With