¿Cómo manejar la respuesta 204 en Retrofit usando Kotlin Coroutines?

2 minutos de lectura

Avatar de usuario de PhillyTheThrilly
PhillyTheThrally

Estoy usando Retrofit 2.7.1 con rutinas Kotlin.

Tengo un servicio Retrofit definido como tal:

@PUT("/users/{userId}.json")
suspend fun updateUserProfile(
        @Path("userId") userId: String,
        @Query("display_name") displayName: String) : Void

Esta llamada devuelve un HTTP 204 Sin contenido respuesta, lo que provoca un bloqueo en 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)

¿Cómo manejo una respuesta 204 en actualización, usando corrutinas, sin fallar?

  • Posiblemente respondido aquí: stackoverflow.com/questions/37116364/…

    – CoryRoy

    7 de enero de 2020 a las 21:33

Avatar de usuario de Dmitri
Dmitri

De acuerdo con esto, utiliza Response<Unit> en la declaración del método de actualización.

actualización sin problema de contenido

  • Pasé casi 2 días en este problema, finalmente funciona bien con su solución. gracias.

    – CKT

    4 de agosto de 2020 a las 8:27

  • ¡Esta es una respuesta útil!

    – yoonhok

    10 de marzo de 2022 a las 8:05

  • Si la API puede devolver valores nulos o no nulos, esta solución no funcionará.

    – Juan

    31 de marzo de 2022 a las 12:32

avatar de usuario de savepopulation
guardarpoblacion

Puedes usar Response<Unit> para manejar 204 respuestas usando Retrofit pero cuando te manejas así Retrofit no lanzará una excepción para 4xx respuestas u otros casos excepcionales.

Puede tratar estos casos con el siguiente código:

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!
    }

  • ¿Cómo obtener datos de mensajes de 205?

    – Ralph Gabb

    19 de mayo de 2020 a las 13:37

Avatar de usuario de Kishan Solanki
Kishan Solanki

Explicando la respuesta de @Dmitri con el código de muestra:

  1. En su APIInterface, llame a su API así,

     @GET(AppConstants.APIEndPoints.GET_NEWS)
     suspend fun getNews(
         @Query("limit") limit: String,
     ): Response<NewsListResponseModel>
    

donde, Respuesta es retrofit2.Response

  1. Desde donde llama a la API, verifique el código de estado de la función como 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))
     }
    

  • finalmente está funcionando bien con su solución. gracias.

    – Khaleel_jageer

    16 de enero de 2021 a las 7:02

Avatar de usuario de GiridharaSPK
GiridharaSPK

esto podría ayudar a alguien En el generador de clientes okhttp (para instanciar una instancia de actualización), agregamos encabezados. Agregué encabezados incorrectos que me causaron ese error de solicitud HTTP 400 Bad, eliminando lo siguiente funcionó para mí. Por lo tanto, compruebe el suyo y proceda en consecuencia.

      .addHeader("Content-Encoding", "UTF-8")
      .header("Accept-Encoding", "identity")     

¿Ha sido útil esta solución?