https://kotlinlang.org logo
#ktor
Title
# ktor
h

hellman

01/29/2021, 3:25 PM
I’m not sure if I understand how to use Ktor properly. Unless I get an HTTP 200 Ok, it throws an exception unless I set
expectSuccess
to
false
. But if I do that, I can’t get the deserialized body. This means that when I get a valid response, like
302 Found
, I still get an exception. How is this meant to be used?
r

Rustam Siniukov

01/29/2021, 3:30 PM
what do you mean by you can’t get deserialized body?
h

hellman

01/29/2021, 3:31 PM
If I do like this:
Copy code
val thing = try {
    <http://client.post|client.post><Thing>(url)
} catch (e: RedirectResponseException) { // 3xx response code
    // can't get deserialized body here!
}
r

Rustam Siniukov

01/29/2021, 3:32 PM
e.response.receive<YourDataClass>()
doesn’t work for you? what is the error?
h

hellman

01/29/2021, 3:32 PM
The exception only have the
ByteReadChannel
so I have to do the deserialization myself
Hmmm
Oh, that should probably go into the docs! 😄
r

Rustam Siniukov

01/29/2021, 3:34 PM
yes, we are improving API discoverability here. should be better in next minor/major releases
👍 1
h

hellman

01/29/2021, 3:34 PM
Ok, so now I got a different error:
Copy code
NoTransformationFoundException: No transformation found: class io.ktor.utils.io.ByteBufferChannel (Kotlin reflection is not available) -> class com.Thing (Kotlin reflection is not available)
It doesn’t seem like it uses the serializer?
r

Rustam Siniukov

01/29/2021, 3:36 PM
is it possible that response do not has
ContentType
header?
h

hellman

01/29/2021, 3:36 PM
hm. you’re right, it doesn’t
Can I force that?
r

Rustam Siniukov

01/29/2021, 3:41 PM
not in a simple way. you can create interceptor that will add header to the response, but that’s a bit hacky
h

hellman

01/29/2021, 3:41 PM
Ok. Too bad. That will probably break at a lot of API integrations.. 😕
r

Rustam Siniukov

01/29/2021, 3:42 PM
please create an issue with your concerns, we will take a look at it
h

hellman

01/29/2021, 3:42 PM
Will do!
👍 1
Is there an example of how to intercept the response?
r

Rustam Siniukov

01/29/2021, 4:12 PM
something like this is what you need
Copy code
scope.receivePipeline.intercept(HttpReceivePipeline.After) { response ->
    context.response = object : HttpResponse() {
        override val call: HttpClientCall = response.call
        override val status: HttpStatusCode = response.status
        override val version: HttpProtocolVersion = response.version
        override val requestTime: GMTDate = response.requestTime
        override val responseTime: GMTDate = response.responseTime
        override val content: ByteReadChannel = response.content
        override val headers: Headers = Headers.build { appendAll(response.headers); append(/* you headers*/) }
        override val coroutineContext: CoroutineContext = response.coroutineContext
    }
    proceedWith(context.response)
}
👍 1
h

hellman

01/29/2021, 4:14 PM
hmm..
context.response
only has an internal setter. 😕
Oh, I don’t need to set it!
r

Rustam Siniukov

01/29/2021, 5:41 PM
as another option, you may configure the json feature so that it accepts all responses
this can be better solution depending on your use case
h

hellman

01/29/2021, 5:47 PM
Yep. That solved it. Thanks! I consider this as a bug in our backend so I will file an issue there first. :)
👍 1
21 Views