diff --git a/SpotifyAPI.Web/Models/BasicModel.cs b/SpotifyAPI.Web/Models/BasicModel.cs
index d6f54697..04727628 100644
--- a/SpotifyAPI.Web/Models/BasicModel.cs
+++ b/SpotifyAPI.Web/Models/BasicModel.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
+using SpotifyAPI.Web.Enums;
using System;
using System.Net;
diff --git a/SpotifyAPI.Web/Models/ResponseInfo.cs b/SpotifyAPI.Web/Models/ResponseInfo.cs
index 1a8a12c2..7a794387 100644
--- a/SpotifyAPI.Web/Models/ResponseInfo.cs
+++ b/SpotifyAPI.Web/Models/ResponseInfo.cs
@@ -1,4 +1,5 @@
-using System.Net;
+using SpotifyAPI.Web.Enums;
+using System.Net;
namespace SpotifyAPI.Web.Models
{
diff --git a/SpotifyAPI.Web/SpotifyWebAPI.cs b/SpotifyAPI.Web/SpotifyWebAPI.cs
index 2e628dc2..57f66acd 100644
--- a/SpotifyAPI.Web/SpotifyWebAPI.cs
+++ b/SpotifyAPI.Web/SpotifyWebAPI.cs
@@ -1,4 +1,4 @@
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SpotifyAPI.Web.Enums;
using SpotifyAPI.Web.Models;
@@ -78,6 +78,11 @@ namespace SpotifyAPI.Web
///
public int RetryTimes { get; set; } = 10;
+ ///
+ /// Whether a failure of type "Too Many Requests" should use up one of the allocated retry attempts.
+ ///
+ public bool TooManyRequestsConsumesARetry { get; set; } = false;
+
///
/// Error codes that will trigger auto-retry if is enabled.
///
@@ -2445,6 +2450,26 @@ namespace SpotifyAPI.Web
return response.Item2;
}
+ ///
+ /// Retrieves whether request had a "TooManyRequests" error, and get the amount Spotify recommends waiting before another request.
+ ///
+ /// Info object to analyze.
+ /// Seconds to wait before making another request. -1 if no error.
+ /// AUTH NEEDED
+ private int GetTooManyRequests(ResponseInfo info)
+ {
+ // 429 is "TooManyRequests" value specified in Spotify API
+ if (429 != (int)info.StatusCode)
+ {
+ return -1;
+ }
+ if (!int.TryParse(info.Headers.Get("Retry-After"), out var secondsToWait))
+ {
+ return -1;
+ }
+ return secondsToWait;
+ }
+
public async Task DownloadDataAsync(string url) where T : BasicModel
{
int triesLeft = RetryTimes + 1;
@@ -2453,15 +2478,30 @@ namespace SpotifyAPI.Web
Tuple response = null;
do
{
- if (response != null) { await Task.Delay(RetryAfter).ConfigureAwait(false); }
+ if (response != null)
+ {
+ int msToWait = RetryAfter;
+ var secondsToWait = GetTooManyRequests(response.Item1);
+ if (secondsToWait > 0)
+ {
+ msToWait = secondsToWait * 1000;
+ }
+ await Task.Delay(msToWait).ConfigureAwait(false);
+ }
response = await DownloadDataAltAsync(url).ConfigureAwait(false);
response.Item2.AddResponseInfo(response.Item1);
lastError = response.Item2.Error;
- triesLeft -= 1;
+ if (TooManyRequestsConsumesARetry || GetTooManyRequests(response.Item1) == -1)
+ {
+ triesLeft -= 1;
+ }
- } while (UseAutoRetry && triesLeft > 0 && lastError != null && RetryErrorCodes.Contains(lastError.Status));
+ } while (UseAutoRetry
+ && triesLeft > 0
+ && (GetTooManyRequests(response.Item1) != -1
+ || (lastError != null && RetryErrorCodes.Contains(lastError.Status))));
return response.Item2;
diff --git a/SpotifyAPI.Web/SpotifyWebClient.cs b/SpotifyAPI.Web/SpotifyWebClient.cs
index b8c5c094..7c3a572b 100644
--- a/SpotifyAPI.Web/SpotifyWebClient.cs
+++ b/SpotifyAPI.Web/SpotifyWebClient.cs
@@ -1,4 +1,4 @@
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
@@ -7,6 +7,7 @@ using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using SpotifyAPI.Web.Models;
+using SpotifyAPI.Web.Enums;
namespace SpotifyAPI.Web
{