Skip to content

Commit ce8997d

Browse files
committed
add option to retry on internal server error
Signed-off-by: Adam Ratzman <[email protected]>
1 parent ff9491a commit ce8997d

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

src/commonMain/kotlin/com.adamratzman.spotify/Builder.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,8 @@ public class SpotifyUserAuthorization(
846846
* @param requiredScopes Scopes that your application requires to function (only applicable to [SpotifyClientApi] and [SpotifyImplicitGrantApi]).
847847
* @param proxyBaseUrl Provide if you have a proxy base URL that you would like to use instead of the Spotify API base
848848
* (https://api.spotify.com/v1).
849+
* @param retryIfInternalServerError Whether to retry once if an internal server error (500..599) has been received
850+
*
849851
*/
850852
public data class SpotifyApiOptions(
851853
public var useCache: Boolean = true,
@@ -861,5 +863,6 @@ public data class SpotifyApiOptions(
861863
public var refreshTokenProducer: (suspend (GenericSpotifyApi) -> Token)? = null,
862864
public var onTokenRefresh: (suspend (GenericSpotifyApi) -> Unit)? = null,
863865
public var requiredScopes: List<SpotifyScope>? = null,
864-
public var proxyBaseUrl: String? = null
866+
public var proxyBaseUrl: String? = null,
867+
public var retryIfInternalServerError: Boolean = true
865868
)

src/commonMain/kotlin/com.adamratzman.spotify/http/Endpoints.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
8787
return withTimeout(api.spotifyApiOptions.requestTimeoutMillis ?: 100 * 1000L) {
8888
try {
8989
val document = createConnection(url, body, method, contentType).execute(
90-
cacheState?.eTag?.let {
90+
additionalHeaders = cacheState?.eTag?.let {
9191
listOf(HttpHeader("If-None-Match", it))
92-
}
92+
},
93+
retryIfInternalServerError = api.spotifyApiOptions.retryIfInternalServerError
9394
)
9495

9596
handleResponse(document, cacheState, spotifyRequest, retry202) ?: execute(
@@ -100,7 +101,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
100101
contentType
101102
)
102103
} catch (e: BadRequestException) {
103-
if (e.statusCode?.equals(401) == true && !attemptedRefresh) {
104+
if (e.statusCode == 401 && !attemptedRefresh) {
104105
api.refreshToken()
105106

106107
execute(
@@ -147,7 +148,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
147148
}
148149
}
149150

150-
if (document.responseCode / 200 != 1 /* Check if status is not 2xx or 3xx */) {
151+
if (document.responseCode !in 200..399 /* Check if status is not 2xx or 3xx */) {
151152
val response = try {
152153
document.body.toObject(ErrorResponse.serializer(), api, api.spotifyApiOptions.json)
153154
} catch (e: Exception) {

src/commonMain/kotlin/com.adamratzman.spotify/http/HttpConnection.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,23 @@ public class HttpConnection constructor(
8585

8686
public suspend fun execute(
8787
additionalHeaders: List<HttpHeader>? = null,
88-
retryIf502: Boolean = true
88+
retryIfInternalServerError: Boolean = true
8989
): HttpResponse {
9090
val httpRequest = buildRequest(additionalHeaders)
9191

9292
try {
9393
return HttpClient().request<io.ktor.client.statement.HttpResponse>(httpRequest).let { response ->
9494
val respCode = response.status.value
9595

96-
if (respCode == 502 && retryIf502) {
96+
if (respCode in 500..599 && retryIfInternalServerError) {
9797
api?.logger?.logError(
9898
false,
99-
"Received 502 (Invalid response) for URL $url and $this (${response.readText()})\nRetrying..",
99+
"Received $respCode (Internal Server Error) for URL $url and $this (${response.readText()})\nRetrying..",
100100
null
101101
)
102-
return@let execute(additionalHeaders, retryIf502 = false)
103-
} else if (respCode == 502 && !retryIf502) {
104-
api?.logger?.logWarning("Recieved 502 (Invalid response) for URL $url and $this\nNot retrying")
102+
return@let execute(additionalHeaders, retryIfInternalServerError = false)
103+
} else if (respCode in 500..599 && !retryIfInternalServerError) {
104+
api?.logger?.logWarning("Received $respCode (Internal Server Error) for URL $url and $this\nNot retrying")
105105
}
106106

107107
if (respCode == 429) {
@@ -114,7 +114,7 @@ public class HttpConnection constructor(
114114
)
115115

116116
delay(ratelimit * 1000)
117-
return@let execute(additionalHeaders, retryIf502 = retryIf502)
117+
return@let execute(additionalHeaders, retryIfInternalServerError = retryIfInternalServerError)
118118
} else throw SpotifyRatelimitedException(ratelimit)
119119
}
120120

@@ -125,7 +125,7 @@ public class HttpConnection constructor(
125125
api.refreshToken()
126126
val newAdditionalHeaders = additionalHeaders?.toMutableList() ?: mutableListOf()
127127
newAdditionalHeaders.add(0, HttpHeader("Authorization", "Bearer ${api.token.accessToken}"))
128-
return execute(newAdditionalHeaders, retryIf502)
128+
return execute(newAdditionalHeaders, retryIfInternalServerError)
129129
}
130130

131131
return HttpResponse(

0 commit comments

Comments
 (0)