mirror of
https://github.com/Sarsoo/Spotify.NET.git
synced 2024-12-24 06:56:27 +00:00
TooManyRequests Handling (#282)
* SpotifyHttpStatusCode A small supplementary enum for Spotify specific codes. Only contains TooManyRequests currently, but more can be added. * TooManyRequests Retry Handling Will now parse and wait the Spotify recommended wait time. Also has the option to not consume a retry attempt on this type of error * TryGetTooManyRequests refactored to GetTooManyRequests To keep the library consistent * Removed SpotifyHttpStatusCode
This commit is contained in:
parent
fa0f3e2d90
commit
67cb3e42f1
@ -1,4 +1,5 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using SpotifyAPI.Web.Enums;
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Net;
|
using SpotifyAPI.Web.Enums;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace SpotifyAPI.Web.Models
|
namespace SpotifyAPI.Web.Models
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using SpotifyAPI.Web.Enums;
|
using SpotifyAPI.Web.Enums;
|
||||||
using SpotifyAPI.Web.Models;
|
using SpotifyAPI.Web.Models;
|
||||||
@ -78,6 +78,11 @@ namespace SpotifyAPI.Web
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int RetryTimes { get; set; } = 10;
|
public int RetryTimes { get; set; } = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether a failure of type "Too Many Requests" should use up one of the allocated retry attempts.
|
||||||
|
/// </summary>
|
||||||
|
public bool TooManyRequestsConsumesARetry { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error codes that will trigger auto-retry if <see cref="UseAutoRetry"/> is enabled.
|
/// Error codes that will trigger auto-retry if <see cref="UseAutoRetry"/> is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -2445,6 +2450,26 @@ namespace SpotifyAPI.Web
|
|||||||
return response.Item2;
|
return response.Item2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves whether request had a "TooManyRequests" error, and get the amount Spotify recommends waiting before another request.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">Info object to analyze.</param>
|
||||||
|
/// <returns>Seconds to wait before making another request. -1 if no error.</returns>
|
||||||
|
/// <remarks>AUTH NEEDED</remarks>
|
||||||
|
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<T> DownloadDataAsync<T>(string url) where T : BasicModel
|
public async Task<T> DownloadDataAsync<T>(string url) where T : BasicModel
|
||||||
{
|
{
|
||||||
int triesLeft = RetryTimes + 1;
|
int triesLeft = RetryTimes + 1;
|
||||||
@ -2453,15 +2478,30 @@ namespace SpotifyAPI.Web
|
|||||||
Tuple<ResponseInfo, T> response = null;
|
Tuple<ResponseInfo, T> response = null;
|
||||||
do
|
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<T>(url).ConfigureAwait(false);
|
response = await DownloadDataAltAsync<T>(url).ConfigureAwait(false);
|
||||||
|
|
||||||
response.Item2.AddResponseInfo(response.Item1);
|
response.Item2.AddResponseInfo(response.Item1);
|
||||||
lastError = response.Item2.Error;
|
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;
|
return response.Item2;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -7,6 +7,7 @@ using System.Net.Http.Headers;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SpotifyAPI.Web.Models;
|
using SpotifyAPI.Web.Models;
|
||||||
|
using SpotifyAPI.Web.Enums;
|
||||||
|
|
||||||
namespace SpotifyAPI.Web
|
namespace SpotifyAPI.Web
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user