diff --git a/app/src/main/java/chat/revolt/activities/MainActivity.kt b/app/src/main/java/chat/revolt/activities/MainActivity.kt index 5a94b959..f8ff6e2b 100644 --- a/app/src/main/java/chat/revolt/activities/MainActivity.kt +++ b/app/src/main/java/chat/revolt/activities/MainActivity.kt @@ -39,6 +39,7 @@ import androidx.navigation.compose.rememberNavController import chat.revolt.BuildConfig import chat.revolt.R import chat.revolt.RevoltApplication +import chat.revolt.api.HitRateLimitException import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltHttp import chat.revolt.api.routes.onboard.needsOnboarding @@ -170,6 +171,14 @@ class MainActivityViewModel @Inject constructor( startWithDestination("register/onboarding") return@launch } + } catch (e: HitRateLimitException) { + Log.e("MainActivity", "Rate limited while checking onboarding state", e) + Toast.makeText( + context, + context.getString(R.string.rate_limit_toast), + Toast.LENGTH_SHORT + ).show() + return@launch startWithoutDestination() } catch (e: Exception) { Log.e("MainActivity", "Failed to check onboarding state, clearing session", e) kvStorage.remove("sessionToken") diff --git a/app/src/main/java/chat/revolt/api/RevoltAPI.kt b/app/src/main/java/chat/revolt/api/RevoltAPI.kt index 86216d6a..fff3032e 100644 --- a/app/src/main/java/chat/revolt/api/RevoltAPI.kt +++ b/app/src/main/java/chat/revolt/api/RevoltAPI.kt @@ -41,6 +41,7 @@ import kotlinx.coroutines.newSingleThreadContext import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.cbor.Cbor import kotlinx.serialization.json.Json @@ -349,3 +350,13 @@ object RevoltAPI { @Serializable data class RevoltError(val type: String) + +@Serializable +data class RateLimitResponse(@SerialName("retry_after") val retryAfter: Int) { + fun toException(): HitRateLimitException { + return HitRateLimitException(retryAfter) + } +} + +class HitRateLimitException(retryAfter: Int) : + Exception("Hit rate limit, retry after ${retryAfter}ms") \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/api/routes/onboard/Onboarding.kt b/app/src/main/java/chat/revolt/api/routes/onboard/Onboarding.kt index e32b4dd2..37d3c7c7 100644 --- a/app/src/main/java/chat/revolt/api/routes/onboard/Onboarding.kt +++ b/app/src/main/java/chat/revolt/api/routes/onboard/Onboarding.kt @@ -1,5 +1,6 @@ package chat.revolt.api.routes.onboard +import chat.revolt.api.RateLimitResponse import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltError import chat.revolt.api.RevoltHttp @@ -28,6 +29,14 @@ suspend fun needsOnboarding(sessionToken: String = RevoltAPI.sessionToken): Bool val responseContent = response.bodyAsText() + try { + val rateLimitResponse = + RevoltJson.decodeFromString(RateLimitResponse.serializer(), responseContent) + throw rateLimitResponse.toException() + } catch (e: SerializationException) { + // good path + } + return RevoltJson.decodeFromString(OnboardingResponse.serializer(), responseContent).onboarding } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 628e153a..8363520c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Share Let\'s go Fetching some info, hang in there… + Hold your horses! You\'re doing that too often in a short amount of time. Terms of Service Privacy Policy