Skip to content

Commit 8fcc011

Browse files
committed
show message for api ratelimits
1 parent 6c62229 commit 8fcc011

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

app/src/main/java/com/geode/launcher/updater/ReleaseRepository.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.geode.launcher.updater
22

33
import com.geode.launcher.utils.DownloadUtils.executeCoroutine
4+
import kotlinx.datetime.Clock
5+
import kotlinx.datetime.DateTimeUnit
6+
import kotlinx.datetime.Instant
7+
import kotlinx.datetime.until
48
import kotlinx.serialization.ExperimentalSerializationApi
59
import kotlinx.serialization.json.Json
610
import kotlinx.serialization.json.JsonNamingStrategy
@@ -15,6 +19,9 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
1519
private const val GITHUB_API_BASE = "https://api.github.com"
1620
private const val GITHUB_API_HEADER = "X-GitHub-Api-Version"
1721
private const val GITHUB_API_VERSION = "2022-11-28"
22+
23+
private const val GITHUB_RATELIMIT_REMAINING = "x-ratelimit-remaining"
24+
private const val GITHUB_RATELIMIT_RESET = "x-ratelimit-reset"
1825
}
1926

2027
suspend fun getLatestLauncherRelease(): Release? {
@@ -35,6 +42,15 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
3542
return getReleaseByUrl(url)
3643
}
3744

45+
private fun generateRateLimitMessage(resetTime: Instant): String {
46+
val currentTime = Clock.System.now()
47+
val resetDelay = currentTime.until(resetTime, DateTimeUnit.SECOND)
48+
49+
val formattedWait = "${resetDelay / 60}m"
50+
51+
return "api ratelimit reached, try again in ${formattedWait}"
52+
}
53+
3854
@OptIn(ExperimentalSerializationApi::class)
3955
private suspend fun getReleaseByUrl(url: URL): Release? {
4056
val request = Request.Builder()
@@ -59,6 +75,24 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
5975

6076
release
6177
}
78+
403 -> {
79+
// determine if the error code is a ratelimit
80+
// (github docs say it sends 429 too, but haven't seen that)
81+
82+
val limitRemaining = response.headers.get(GITHUB_RATELIMIT_REMAINING)?.toInt()
83+
val limitReset = response.headers.get(GITHUB_RATELIMIT_RESET)?.toLong()
84+
85+
if (limitRemaining == 0 && limitReset != null) {
86+
// handle ratelimit with a custom error
87+
// there's also a retry-after header but again, haven't seen
88+
val resetTime = Instant.fromEpochSeconds(limitReset, 0L)
89+
val msg = generateRateLimitMessage(resetTime)
90+
91+
throw IOException(msg)
92+
}
93+
94+
throw IOException("response 403: ${response.body!!.string()}")
95+
}
6296
404 -> {
6397
null
6498
}

0 commit comments

Comments
 (0)