'How to throw Custom exception in ktor

Hey I am working in ktor. I want to throw exception in ktor. I am reading this doc and this example. I want exception, responseCode and errorResponse with errorCode and errorMessage.

commanMain

ApiResponse.kt

package com.example.kotlinmultiplatformsharedmodule

import kotlinx.serialization.Serializable

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

    data class Error(
        val exception: Throwable? = null,
        val responseCode: Int = -1,
        val errorResponse: ErrorResponse? = null
    ) : 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(
    val errorCode: Int,
    val errorMessage: String
)

I created one class called CustomException but I don't understand How to send this value this class and send in catch block.

CustomeException.kt

class CustomeException {

}

KtorApi.kt

class KtorApi : NetworkRoute(), KoinComponent {
    private val httpClient by inject<HttpClient>()
    suspend fun getApi(): ApiResponse<KtorResponse> {
        val response = httpClient.get {
            url("xyz")
        }
        return apiCall(response)
    }
}

NetworkRoute.kt

open class NetworkRoute {
    suspend inline fun <reified T : Any> apiCall(httpResponse: HttpResponse): ApiResponse<T> {
        return try {
            ApiResponse.Success(httpResponse.body())
        } catch (e: Exception) {
             // how to send all details in ApiResponse.Error()
            ApiResponse.Error()
        }
    }
}

I created a NetworkRoute to send body and response according to route.

androidMain

HttpClient.kt

actual fun httpClient(config: HttpClientConfig<*>.() -> Unit) = HttpClient(OkHttp) {
    config(this)
    install(Logging) {
        logger = Logger.SIMPLE
        level = LogLevel.BODY
    }
    expectSuccess = false
    install(HttpCallValidator) {
        handleResponseExceptionWithRequest { exception, _ ->
            val customNetworkError = when (exception) {
                is ResponseException -> "Response Error"
                is ClientRequestException -> "Client Error"
                is JsonConvertException -> "Json Error"
                is SerializationException -> "Serialize Error"
                else -> "Don't know"
            }
            println("customNetworkError $customNetworkError and ${exception}")
        }
    }
}

I tried some code but I don't understand how to throw exception in handleResponseExceptionWithRequest.

UPDATE

I found this solution and trying to modify according to my requirements to throw exception. But I am getting unresolved refrence.

install(HttpCallValidator) {
     handleResponseExceptionWithRequest { exception, _ ->
         val error = exception.response.body<ErrorResponse>()
     }
}  

The response attribute is unavailable.

enter image description here

I tried some code after suggestions

install(HttpCallValidator) {
        handleResponseExceptionWithRequest { exception, _ ->
            if (exception !is ClientRequestException) return@handleResponseExceptionWithRequest
            val error = exception.response.body<ErrorResponse>()
            throw CustomException(statusCode = exception.response.status.value, errorResponse = error)
        }
    }

CustomException.kt

class CustomException(var statusCode: Int, var errorResponse: ErrorResponse) : Exception()

My exception variable is null

return try {
            val response = httpClient.get {
                url(urlString)
            }
            ApiResponse.Success(response.body())
        } catch (e: LgcException) {
            ApiResponse.Error(
                exception = e,
                responseCode = e.statusCode,
                errorResponse = e.errorResponse
            )
        }

when I am printing e.message or e.cause it printing null value.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source