Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

934
Visualizações
Handling Exception in HttpClient Ktor

I have written a common code in a common module as below and tested in JS environment

val response = client.post<HttpResponse>(url) {
    body = TextContent("""{"a":1,"b":2}""", ContentType.Application.Json)
}
if (response.status != HttpStatusCode.OK) {
    logger.error("Error, this one failed bad?")
}

But my code ends at client.post with a canceled corutineException on no network. How do I handle this and any other exception? If there is an internet connection. Nothing fails, I want to be able to handle the exceptions. How?

Note: try, catch doesn't work

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Not adding much to the current answer but in response to CVS's comment I've been using the following to add ktor client error handling in my applications. It makes use of the Result API. runCatching {} catches all Throwables and you can tweak the behaviour of the getOrElse block to capture the exceptions you're interested in.

suspend fun <T> HttpClient.requestAndCatch(
    block: suspend HttpClient.() -> T,
    errorHandler: suspend ResponseException.() -> T
): T = runCatching { block() }
    .getOrElse {
        when (it) {
            is ResponseException -> it.errorHandler()
            else -> throw it
        }
    }

// Example call
client.requestAndCatch(
    { get<String>("/") },
    {
        when (response.status) {
            HttpStatusCode.BadRequest -> {} // Throw errors or transform to T 
            HttpStatusCode.Conflict -> {}
            else -> throw this
        }
    }
)

I'm sure it could be made tidier but it's the best I've come up with so far.

over 4 years ago · Santiago Trujillo Relatório

0

well after asking here and there, I got help from github issues and came to this work arround

try {
    val response = client.post<HttpResponse>(url) {
        body = TextContent("""{"a":1,"b":2}""", ContentType.Application.Json)
    }
    if (response.status != HttpStatusCode.OK) {
        logger.error("Error, this one failed bad?")
    }
} catch (cause: Throwable) {
    logger.error("Catch your error here")
}

don't confuse to catch (c: Throwable) with catch (e: Exception)

hope this helps

over 4 years ago · Santiago Trujillo Relatório

0

We can handle it in a central way using this extension function that wraps Success and error cases. We can have Network Error, Serialisation Error or Server Errors which may expose error bodies/messages for the UI and http status code.

suspend inline fun <reified T, reified E> HttpClient.safeRequest(
    block: HttpRequestBuilder.() -> Unit,
): ApiResponse<T, E> =
    try {
        val response = request { block() }
        ApiResponse.Success(response.body())
    } catch (e: ClientRequestException) {
        ApiResponse.Error.HttpError(e.response.status.value, e.errorBody())
    } catch (e: ServerResponseException) {
        ApiResponse.Error.HttpError(e.response.status.value, e.errorBody())
    } catch (e: IOException) {
        ApiResponse.Error.NetworkError
    } catch (e: SerializationException) {
        ApiResponse.Error.SerializationError
    }

suspend inline fun <reified E> ResponseException.errorBody(): E? =
    try {
        response.body()
    } catch (e: SerializationException) {
        null
    }

Here's the ApiResponse defined below so there's working code:

sealed class ApiResponse<out T, out E> {
    /**
     * Represents successful network responses (2xx).
     */
    data class Success<T>(val body: T) : ApiResponse<T, Nothing>()

    sealed class Error<E> : ApiResponse<Nothing, E>() {
        /**
         * Represents server (50x) and client (40x) errors.
         */
        data class HttpError<E>(val code: Int, val errorBody: E?) : Error<E>()

        /**
         * Represent IOExceptions and connectivity issues.
         */
        object NetworkError : Error<Nothing>()

        /**
         * Represent SerializationExceptions.
         */
        object SerializationError : Error<Nothing>()
    }
}

I found ApiResponse works well for my case but you don't necessarily have to model your api responses as this if you have other/special cases, you can also use kotlin-result or Arrow's Either.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda