Skip to content

Commit 28e45fe

Browse files
committed
Fixed issue where endpoint would infinitely retry for a nullable resource
Recently a new method in Endpoints.kt called "getNullable" has been added. However, the execute method was not appropriately changed, leading to the method infinitely retrying the request when the result was null. Closes #312
1 parent 01afa60 commit 28e45fe

File tree

1 file changed

+16
-15
lines changed
  • src/commonMain/kotlin/com.adamratzman.spotify/http

1 file changed

+16
-15
lines changed

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,12 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
7575
}
7676
}
7777

78-
7978
internal suspend fun get(url: String): String {
8079
return execute<String>(url)
8180
}
8281

8382
internal suspend fun getNullable(url: String): String? {
84-
return execute<String?>(url)
83+
return execute<String?>(url, retryOnNull = false)
8584
}
8685

8786
internal suspend fun post(url: String, body: String? = null, contentType: String? = null): String {
@@ -100,14 +99,16 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
10099
return execute<String>(url, body, HttpRequestMethod.DELETE, contentType = contentType)
101100
}
102101

103-
private suspend fun <T: String?> execute(
102+
@Suppress("UNCHECKED_CAST")
103+
private suspend fun <ReturnType: String?> execute(
104104
url: String,
105105
body: String? = null,
106106
method: HttpRequestMethod = HttpRequestMethod.GET,
107107
retry202: Boolean = true,
108108
contentType: String? = null,
109-
attemptedRefresh: Boolean = false
110-
): String {
109+
attemptedRefresh: Boolean = false,
110+
retryOnNull: Boolean = true
111+
): ReturnType {
111112
if (api.token.shouldRefresh()) {
112113
if (!api.spotifyApiOptions.automaticRefresh) throw SpotifyException.ReAuthenticationNeededException(message = "The access token has expired.")
113114
else api.refreshToken()
@@ -116,7 +117,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
116117
val spotifyRequest = SpotifyRequest(url, method, body, api)
117118
val cacheState = if (api.useCache) cache[spotifyRequest] else null
118119

119-
if (cacheState?.isStillValid() == true) return cacheState.data
120+
if (cacheState?.isStillValid() == true) return cacheState.data as ReturnType
120121
else if (cacheState?.let { it.eTag == null } == true) {
121122
cache -= spotifyRequest
122123
}
@@ -131,18 +132,18 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
131132
retryIfInternalServerErrorLeft = api.spotifyApiOptions.retryOnInternalServerErrorTimes
132133
)
133134

134-
handleResponse(document, cacheState, spotifyRequest, retry202) ?: execute<T>(
135-
url,
136-
body,
137-
method,
138-
false,
139-
contentType
140-
)
135+
handleResponse(document, cacheState, spotifyRequest, retry202) ?: run {
136+
if (retryOnNull) {
137+
execute<ReturnType>(url, body, method, false, contentType)
138+
} else {
139+
null
140+
}
141+
}
141142
} catch (e: BadRequestException) {
142143
if (e.statusCode == 401 && !attemptedRefresh) {
143144
api.refreshToken()
144145

145-
execute<T>(
146+
execute<ReturnType>(
146147
url,
147148
body,
148149
method,
@@ -152,7 +153,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
152153
)
153154
} else throw e
154155
}
155-
}
156+
} as ReturnType
156157
} catch (e: CancellationException) {
157158
throw TimeoutException(
158159
e.message

0 commit comments

Comments
 (0)