How to get status code of HttpCall with Ktor and kotlinx serialization
Asked Answered
C

3

7

I am trying to figure out how to check the http status code of a http request with Ktor

I have a simple GET request like this with a HttpResponseObject that holds the data the server returns and any errors server side that I control

val response:HttpResponseObject<MyObject> = client.get<HttpResponseObject<MyObject>>(url)

Now what I need to also be able to check are is if there are unhandled exceptions or Authentication exceptions that get thrown by the server. In these cases nothing would be returned by the server and a status code of 500 or 401 error would be returned.

I see the documentation has you can get the full http response with something like this

val response:HttpResponse client.get(url)

but then how do lose my serialized data coming back and I couldnt find any examples on how to serialize it from the HttpResponse object.

Does anyone have any suggestions? is there a way to get the http status code from my first example?

Clypeate answered 4/5, 2020 at 20:4 Comment(0)
C
1

What I ended up doing was using the HttpResponseValidator in the HttpClientConfig to catch the status codes then throw exceptions

HttpResponseValidator{

            validateResponse { response: HttpResponse ->
                val statusCode = response.status.value
                when (statusCode) {
                    in 300..399 -> throw RedirectResponseException(response)
                    in 400..499 -> throw ClientRequestException(response)
                    in 500..599 -> throw ServerResponseException(response)
                }

                if (statusCode >= 600) {
                    throw ResponseException(response)
                }
            }
        }

By doing so I was then able to pass the error through my custom object back up to the UI

private suspend fun getCurrentWeatherForUrl(url:String, callback: (HttpResponseObject<MyObject>?) -> Unit){
        var response:HttpResponseObject<MyObject>? = null
        response = try{
            client.get<HttpResponseObject<MyObject>>(url){
                header("Authorization", "Bearer $authKey")
            }
        }catch (e:Exception){
            HttpResponseObject(null, e.toString())
        }

        callback(response)
    }

Also you can use HttpResponse.receive() to get a serialized object AND the response data

val response:HttpResponse = client.get(url)
val myObject:MyObject = response.receive<MyObject>()
Clypeate answered 12/5, 2020 at 2:28 Comment(1)
What is HttpResponseObject?Midlothian
C
0

You can try getting the status code by using the following code: val response = client.get<HttpResponse>(url) after that, to get the bytes from the response and serialize it you can try using val bytes: ByteArray = response.readBytes()

You can find full documentation here : https://ktor.io/clients/http-client/quick-start/responses.html

Civies answered 7/5, 2020 at 10:11 Comment(3)
Yeah but then How do I deserialize the data into my object?Clypeate
Depends. If the status code is returned as plain text you have but to decode the bytes using utf-8 or ASCII and copy the string in your class.Civies
Looking further that HttpResponse is deprecated for this api.ktor.io/1.3.2/io.ktor.client.statement/-http-response/… which only has a ByteReadChannelClypeate
O
0

HttpResponse is deprecated, you need to use HttpStatement and then get the status after calling execute() on it.

Oolite answered 12/8, 2022 at 16:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.