1

I am learning Ktor. I want to print error value or exception. I have taken some piece of code from this post. I don't understand this post answer fully.

ApiResponse.kt

sealed class ApiResponse<out T : Any> {
    data class Success<out T : Any>(
        val data: T?
    ) : ApiResponse<T>()

    data class Error(
        val responseCode: Int = -1,
    ) : ApiResponse<Nothing>()

    fun handleResult(onSuccess: ((responseData: T?) -> Unit)?, onError: ((error: Error) -> Unit)?) {
        when (this) {
            is Success -> {
                onSuccess?.invoke(this.data)
            }
            is Error -> {
                onError?.invoke(this)
            }
        }
    }
}

@Serializable
data class ErrorResponse(
    var errorCode: Int = 1,
    val errorMessage: String = "Something went wrong"
)

KtorApi.kt

class KtorApi(private val httpClient: HttpClient) : NetworkRoute() {
    suspend fun getCat(): Response<CatResponse> {
        val response = httpClient.get {
            url("https://xyz/cat")
        }
        return apiCall(response)
    }
}

CatResponse.kt

@Serializable
data class CatResponse(
    val items: List<CatDetails>? = null
)

@Serializable
data class CatDetails(
    val id: String? = null,
    val name: String? = null,
)

ViewModel.kt

fun getCat() {
        viewModelScope.launch {
            KtorApi.getCat().handleResult({ data ->
                logE("Success on cat api response->>> $data")
            }) { error ->
                logE("Error on cat api ->>>> $error ")
            }
        }
   }

Here I have successfully get the data from the Success but I don't know how to get error or exception in error.

actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp) {
    config(this)
    install(Logging) {
        logger = Logger.SIMPLE
        level = LogLevel.BODY
    }
    expectSuccess = false
    install(ContentNegotiation) {
        json(Json {
            prettyPrint = true
            ignoreUnknownKeys = true
            explicitNulls = false
        })
    }
}     

How can I pass my exception or error code, status, body in my ERROR data class? Anyone have an idea about that?

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40

1 Answers1

0

With kotlin suspend functions you need to catch errors using try/catch block:

val apiResponse = try {
    ApiResponse.Success(KtorApi.getCat())
} catch (e: ClientRequestException) {
    ApiResponse.Error(e.response.status)
} catch (e: Exeption) {
    // some other error
    ApiResponse.Error()
}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • Hey @PylypDukhov what is the use of `handleResponseExceptionWithRequest` this function in httpClient? I am little bit confused. Thanks –  May 03 '22 at 09:01
  • @ShreyaTiwari you can catch all exceptions there and throw your custom exception on demand. See [this](https://ktor.io/docs/response-validation.html#non-2xx) doc example – Phil Dukhov May 03 '22 at 10:26
  • thanks for giving me example. But there is only one `ResponseException` example. Can you tell me more about more exception? –  May 03 '22 at 12:18
  • @ShreyaTiwari I am not a lecturer to speak in general terms, please be specific – Phil Dukhov May 04 '22 at 04:53
  • How can I pass my exception or error code, status, body in my ERROR data class? –  May 06 '22 at 10:15