Search code examples
retrofit2android-jetpack-compose

How to validate if call was succed with Retrofit in Kotlin


I have a method calling API to create user but sometimes when fails and API returns HTTP 400 Bad Request I cannot be able to validate that state:

private suspend fun createUserPrepare():Boolean{
        var result=false
        try {
            val retrofit=retrofit.getInstance()
            val payload=registerPayload()
            val requestBody = payload.toRequestBody("application/json".toMediaTypeOrNull())
            CoroutineScope(Dispatchers.IO).launch {
                //pass body to request
                val response = retrofit.createUser(requestBody)
                
                    withContext(Dispatchers.Main) {

                        // Convert raw JSON to pretty JSON using GSON library
                        val gson = GsonBuilder().setPrettyPrinting().create()

                        val prettyJson = gson.toJson(
                            JsonParser.parseString(
                                response?.string()
                            )
                        )
                        result=true
                        Log.d("Pretty Printed JSON :", prettyJson)
                    }
            }
        }catch (err:Error){
            Log.d("ERROR",err!!.toString())
        }
        return result
    }

How can i validate status response? (HTTP 400 Bad Request or 200 Ok)


Solution

  • you can create sealed Response class for handling API Response

    sealed class Response<out T> {
        object Loading: Response<Nothing>()
    
        data class Success<out T>(
            val data: T
        ): Response<T>()
    
        data class Error(
            val message: String
        ): Response<Nothing>()
    }
    

    and return this class with flow:

    private suspend fun createUserPrepare(): Flow<Response<Unit>> = flow {
        try {
                emit(Response.Loading)
    
                // api call result
       
                emit(Response.Success(result))
    
        }catch (e: Exception) {
                e.printStackTrace()
                emit(Response.Error(e.message ?: AN_ERROR_OCCURRED))
        }
    }
    

    get values from viewmodel, use case or screen etc:

    createUserPrepare().collect { response ->
        when(response){
            is Response.Error -> { 
                // Handle error  
                response.message //-> This is where we get the error messages
            }
            Response.Loading -> { 
                // Handle loading 
            }
            is Response.Success -> { 
               // Handle success 
            }
        }
    }