Hello guys, I’m pretty new to KTOR and Kotlin in g...
# ktor
g
Hello guys, I’m pretty new to KTOR and Kotlin in general… I’ve created a simple multiplatform project, and I’m calling the following endpoint from the iOS side:
<https://api.github.com/projects/columns/42>
in order to receive 401, which is intended. Unfortunately, the program crashes with the following explanation:
Copy code
Exception doesn't match @Throws-specified class list and thus isn't propagated from Kotlin to Objective-C/Swift as NSError.
It is considered unexpected and unhandled instead. Program will be terminated.
Uncaught Kotlin exception: io.ktor.client.features.ClientRequestException: Client request(<https://api.github.com/projects/columns/42>) invalid: 401 Unauthorized. Text: "{"message":"Requires authentication","documentation_url":"<https://docs.github.com/rest/reference/projects#get-a-project-column>"}"
I get back the response and everything gets logged properly. Any idea on how to fix this? Thanks!
r
you can disable default request validation by setting
expectSuccess = false
on client or per-request level
g
Yeah, I figured that one out, thanks 🙂
I also need help with the following:
Copy code
this.install(HttpSend) {
            intercept { httpClientCall, httpRequestBuilder ->
                val statusCode = httpClientCall.response.status.value

                if (statusCode !in 100..399) {
                    val delayBetweenRequests = retryStrategy.retryDelay(httpClientCall) ?: 0.0
                    delay(maxOf(delayBetweenRequests, 0.0).toLong())
                    execute(httpRequestBuilder)
                } else {
                    httpClientCall
                }
            }

            maxSendCount = retryStrategy.retryCount
        }
    }
For some reason I keep getting the following exception:
Copy code
Uncaught Kotlin exception: io.ktor.client.features.SendCountExceedException: Max send count 3 exceeded
But I don’t understand how this is possible
Also, sorry for being so pushy 😄 I have this:
Copy code
install(Auth) {
        basic {
            username = "myUsername"
            password = "myPassword"
            // sendWithoutRequest = true
        }
    }
Copy code
/**
* Send credentials in without waiting for [HttpStatusCode.Unauthorized].
*/
var sendWithoutRequest: Boolean = false
The request that gets executed returns 401 (Unauthorized) but it doesn’t get re-executed with the
Authorization
header… I can only send it once I set
sendWithoutRequest = true
which I really don’t want to do for every request. Any help would be greatly appreciated! Thanks!
r
for
SendCountExceedException
what exactly is wrong? It seems like you send more then 3 retries, and it’s your current limit
g
This is what I see in
HttpSend.kt
class:
Copy code
if (sentCount >= maxSendCount) {
    throw SendCountExceedException("Max send count $maxSendCount exceeded")
}
So once it reaches 3 it will throw an exception, so I don’t understand how I can fix this on my side? All I do is set the
maxSendCount = 3
in here:
Copy code
this.install(HttpSend) { 
    intercept { httpClientCall, httpRequestBuilder ->
        ...
    }

    maxSendCount = 3
}
I’m probably doing something wrong here I just don’t see it
r
what is your expected behavior?
g
To retry it n times and then just stop retrying. Throwing an exception crashes it on iOS, that’s why this is a problem for me
Copy code
Exception doesn't match @Throws-specified class list and thus isn't propagated from Kotlin to Objective-C/Swift as NSError.
It is considered unexpected and unhandled instead. Program will be terminated.
Uncaught Kotlin exception: io.ktor.client.features.SendCountExceedException: Max send count 3 exceeded
I don’t mind the exception actually. Just need to figure out how to stop the app from crashing once it’s thrown. I’m really new to KMM so sorry if these are stupid questions.
r
you can create a counter on your side and stop calling
execute
in your interceptor once it reaches desired value
something like
Copy code
this.install(HttpSend) {
            var couter = 0
            intercept { httpClientCall, httpRequestBuilder ->
                val statusCode = httpClientCall.response.status.value

                if (counter < 3 && statusCode !in 100..399) {
                    ...
                    execute(httpRequestBuilder)
                    counter++
                } else {
                    httpClientCall
                }
            }
        }
g
Yeah got you, that works. Just to clarify how this mechanism works. It will keep repeating the request until it gets a success response?
r
or you reach desired retry count
g
👍 thanks for your help
r
Hi @Rustam Siniukov. Have very similar case so, will drop my question in this thread. I am using
HttpSend
to intercept response for authentication purposes. On 401/Unauthorized response intercepting and performing actions to refresh token and retry request. When
expectSuccess
is turned on (value true), 401 response is not intercepted. I guess it happens due to
ExpectSuccess
feature, which throws exception just before
HttpSend
feature and stops proceeding ktor pipeline. When I turn off
expectSuccess
(value false), response is intercepted in
HttpSend
and authentication works as expected. However, none of the
HttpResponseValidator
functions (validateResponse and handleResponseException) are called. Can you suggest or what is preferred way to map http errors to custom errors when
expectSuccess
is off?
r
hi @rsetkus. What version of Ktor do you use? We had a bug that
expectSuccess=false
will disable all validators, and not only the default one. It was fixed in 1.5.2 https://youtrack.jetbrains.com/issue/KTOR-2007. Another point, please consider using
Auth
feature and implementing custom
AuthProvider
instead of intercepting
HttpSend
. Internally it will do the same, but it is more idiomatic way. Not a big deal, though
r
Thank you for prompt response @Rustam Siniukov. This is it, I’m using version 1.5.0. Will try to switch to 1.5.2 to see if the issue disappears. Can see that
HttpSend
is marked as experimental so, definitely will consider option re-implement authentication using
AuthProvider
.
r
If you are updating anyway, update to 1.5.3 😃
👍🏻 1
r
Hi @Rustam Siniukov. Updated to 1.5.3. Like you said, it does fix/trigger custom validators but
HttpSend
doesn’t intercept response anymore.
r
@rsetkus can you share example, please?
r
@Rustam Siniukov working an a private project but can try to make a minimal reproducable example.
Hi @Rustam Siniukov. If that helps, then example I followed is this https://github.com/icerockdev/moko-network/issues/37#issuecomment-709420620. Can make complete example if necessary. Let me know.
r
The best is if you create youtrack issue and put reproducer there
130 Views