diff --git a/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt b/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt index 74235023..85b44d68 100644 --- a/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt +++ b/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt @@ -2,10 +2,27 @@ package net.vonforst.evmap.api import okhttp3.Interceptor import okhttp3.Response +import okio.IOException +import retrofit2.HttpException import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlin.time.TimeSource +fun Interceptor.Chain.proceedSafely(request: okhttp3.Request): Response { + return try { + proceed(request) + } catch (e: Throwable) { + if (e is IOException) { + throw e + } else if (e is HttpException) { + // wrap HttpExceptions as IOExceptions, so that they are properly handled by Retrofit's error handling + throw IOException("${e.response()}", e) + } else { + // wrap other exceptions as IOExceptions, so that they are properly handled by Retrofit's error handling + throw IOException(e) + } + } +} class RateLimitInterceptor : Interceptor { private val rateLimiter = SimpleRateLimiter(3.0) @@ -16,7 +33,7 @@ class RateLimitInterceptor : Interceptor { // limit requests sent to NewMotion to 3 per second rateLimiter.acquire() - var response: Response = chain.proceed(request) + var response: Response = chain.proceedSafely(request) // 403 is how the NewMotion API indicates a rate limit error if (!response.isSuccessful && response.code == 403) { response.close() @@ -25,11 +42,11 @@ class RateLimitInterceptor : Interceptor { Thread.sleep(1000) } catch (e: InterruptedException) { } - response = chain.proceed(request) + response = chain.proceedSafely(request) } return response } else { - return chain.proceed(request) + return chain.proceedSafely(request) } } } diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt index 59723fcf..2789cceb 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt @@ -4,6 +4,7 @@ import com.squareup.moshi.FromJson import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi import com.squareup.moshi.ToJson +import net.vonforst.evmap.api.proceedSafely import net.vonforst.evmap.model.ChargeLocation import net.vonforst.evmap.model.Chargepoint import net.vonforst.evmap.utils.distanceBetween @@ -91,7 +92,7 @@ interface EnBwApi { .header("Referer", "https://www.enbw.com/") .header("Accept", "application/json") .build() - chain.proceed(request) + chain.proceedSafely(request) }.build() val retrofit = Retrofit.Builder() .baseUrl(baseUrl ?: "https://enbw-emp.azure-api.net/emobility-public-api/api/v1/") diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaGuestApi.kt b/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaGuestApi.kt index af53fd4b..596be69e 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaGuestApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaGuestApi.kt @@ -3,6 +3,7 @@ package net.vonforst.evmap.api.availability.tesla import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi +import net.vonforst.evmap.api.proceedSafely import okhttp3.CacheControl import okhttp3.OkHttpClient import retrofit2.Retrofit @@ -48,7 +49,7 @@ interface TeslaCuaApi { val request = chain.request().newBuilder() .cacheControl(CacheControl.Builder().maxStale(24, TimeUnit.HOURS).build()) .build() - chain.proceed(request) + chain.proceedSafely(request) }.build() val retrofit = Retrofit.Builder() .baseUrl(baseUrl ?: "https://www.tesla.com/cua-api/") diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaOwnerApi.kt b/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaOwnerApi.kt index bb1cb122..340e9161 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaOwnerApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/tesla/TeslaOwnerApi.kt @@ -7,6 +7,7 @@ import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory import kotlinx.coroutines.runBlocking +import net.vonforst.evmap.api.proceedSafely import okhttp3.OkHttpClient import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory @@ -135,7 +136,7 @@ interface TeslaOwnerApi { .header("x-tesla-user-agent", "TeslaApp/4.44.5-3304/3a5d531cc3/android/27") .header("Accept", "*/*") .build() - chain.proceed(request) + chain.proceedSafely(request) }.build() val retrofit = Retrofit.Builder() .baseUrl(baseUrl ?: "https://owner-api.teslamotors.com") @@ -376,7 +377,7 @@ interface TeslaChargingOwnershipGraphQlApi { .header("x-tesla-user-agent", "TeslaApp/4.44.5-3304/3a5d531cc3/android/27") .header("Accept", "*/*") .build() - chain.proceed(request) + chain.proceedSafely(request) }.build() val retrofit = Retrofit.Builder() .baseUrl(baseUrl ?: "https://akamai-apigateway-charging-ownership.tesla.com") diff --git a/app/src/main/java/net/vonforst/evmap/api/fronyx/FronyxApiRetrofit.kt b/app/src/main/java/net/vonforst/evmap/api/fronyx/FronyxApiRetrofit.kt index c4ab7b3f..8b9234bc 100644 --- a/app/src/main/java/net/vonforst/evmap/api/fronyx/FronyxApiRetrofit.kt +++ b/app/src/main/java/net/vonforst/evmap/api/fronyx/FronyxApiRetrofit.kt @@ -4,6 +4,7 @@ import android.content.Context import com.squareup.moshi.Moshi import net.vonforst.evmap.BuildConfig import net.vonforst.evmap.addDebugInterceptors +import net.vonforst.evmap.api.proceedSafely import net.vonforst.evmap.model.ChargeLocation import net.vonforst.evmap.model.Chargepoint import okhttp3.Cache @@ -46,7 +47,7 @@ private interface FronyxApiRetrofit { .header("X-API-Token", apikey) .header("Content-Type", "application/json") .build() - chain.proceed(new) + chain.proceedSafely(new) } if (BuildConfig.DEBUG) { addDebugInterceptors() diff --git a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricApi.kt b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricApi.kt index a678cfdf..5615fd3a 100644 --- a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricApi.kt @@ -21,6 +21,7 @@ import net.vonforst.evmap.api.mapPower import net.vonforst.evmap.api.mapPowerInverse import net.vonforst.evmap.api.nameForPlugType import net.vonforst.evmap.api.powerSteps +import net.vonforst.evmap.api.proceedSafely import net.vonforst.evmap.model.BooleanFilter import net.vonforst.evmap.model.ChargeLocation import net.vonforst.evmap.model.Chargepoint @@ -131,7 +132,7 @@ interface GoingElectricApi { var original = chain.request() val url = original.url.newBuilder().addQueryParameter("key", apikey).build() original = original.newBuilder().url(url).build() - chain.proceed(original) + chain.proceedSafely(original) } if (BuildConfig.DEBUG) { addDebugInterceptors() diff --git a/app/src/main/java/net/vonforst/evmap/api/openchargemap/OpenChargeMapApi.kt b/app/src/main/java/net/vonforst/evmap/api/openchargemap/OpenChargeMapApi.kt index c4ceb5a2..bb9c2933 100644 --- a/app/src/main/java/net/vonforst/evmap/api/openchargemap/OpenChargeMapApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/openchargemap/OpenChargeMapApi.kt @@ -16,6 +16,7 @@ import net.vonforst.evmap.api.StringProvider import net.vonforst.evmap.api.mapPower import net.vonforst.evmap.api.mapPowerInverse import net.vonforst.evmap.api.powerSteps +import net.vonforst.evmap.api.proceedSafely import net.vonforst.evmap.model.BooleanFilter import net.vonforst.evmap.model.ChargeLocation import net.vonforst.evmap.model.ChargepointListItem @@ -101,7 +102,7 @@ interface OpenChargeMapApi { val new = original.newBuilder() .header("X-API-Key", apikey) .build() - chain.proceed(new) + chain.proceedSafely(new) } if (BuildConfig.DEBUG) { addDebugInterceptors()