Improved discord HTTP exceptions
This commit is contained in:
@@ -5,14 +5,36 @@ namespace Discord.Net
|
|||||||
{
|
{
|
||||||
public class HttpException : Exception
|
public class HttpException : Exception
|
||||||
{
|
{
|
||||||
public HttpStatusCode StatusCode { get; }
|
public HttpStatusCode HttpCode { get; }
|
||||||
|
public int? DiscordCode { get; }
|
||||||
public string Reason { get; }
|
public string Reason { get; }
|
||||||
|
|
||||||
public HttpException(HttpStatusCode statusCode, string reason = null)
|
public HttpException(HttpStatusCode httpCode, int? discordCode = null, string reason = null)
|
||||||
: base($"The server responded with error {(int)statusCode} ({statusCode}){(reason != null ? $": \"{reason}\"" : "")}")
|
: base(CreateMessage(httpCode, discordCode, reason))
|
||||||
{
|
{
|
||||||
StatusCode = statusCode;
|
HttpCode = httpCode;
|
||||||
|
DiscordCode = discordCode;
|
||||||
Reason = reason;
|
Reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string CreateMessage(HttpStatusCode httpCode, int? discordCode = null, string reason = null)
|
||||||
|
{
|
||||||
|
string msg;
|
||||||
|
if (discordCode != null)
|
||||||
|
{
|
||||||
|
if (reason != null)
|
||||||
|
msg = $"The server responded with error {(int)discordCode}: {reason}";
|
||||||
|
else
|
||||||
|
msg = $"The server responded with error {(int)discordCode}: {httpCode}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (reason != null)
|
||||||
|
msg = $"The server responded with error {(int)httpCode}: {reason}";
|
||||||
|
else
|
||||||
|
msg = $"The server responded with error {(int)httpCode}: {httpCode}";
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ namespace Discord.Net.Queue
|
|||||||
await Task.Delay(millis).ConfigureAwait(false);
|
await Task.Delay(millis).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal void PauseGlobal(RateLimitInfo info, TimeSpan lag)
|
internal void PauseGlobal(RateLimitInfo info)
|
||||||
{
|
{
|
||||||
_waitUntil = DateTimeOffset.UtcNow.AddMilliseconds(info.RetryAfter.Value + lag.TotalMilliseconds);
|
_waitUntil = DateTimeOffset.UtcNow.AddMilliseconds(info.RetryAfter.Value + (info.Lag?.TotalMilliseconds ?? 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestBucket GetOrCreateBucket(string id, RestRequest request)
|
private RequestBucket GetOrCreateBucket(string id, RestRequest request)
|
||||||
|
|||||||
@@ -54,12 +54,10 @@ namespace Discord.Net.Queue
|
|||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
Debug.WriteLine($"[{id}] Sending...");
|
Debug.WriteLine($"[{id}] Sending...");
|
||||||
#endif
|
#endif
|
||||||
TimeSpan lag = default(TimeSpan);
|
|
||||||
RateLimitInfo info = default(RateLimitInfo);
|
RateLimitInfo info = default(RateLimitInfo);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await request.SendAsync().ConfigureAwait(false);
|
var response = await request.SendAsync().ConfigureAwait(false);
|
||||||
lag = DateTimeOffset.UtcNow - DateTimeOffset.Parse(response.Headers["Date"]);
|
|
||||||
info = new RateLimitInfo(response.Headers);
|
info = new RateLimitInfo(response.Headers);
|
||||||
|
|
||||||
if (response.StatusCode < (HttpStatusCode)200 || response.StatusCode >= (HttpStatusCode)300)
|
if (response.StatusCode < (HttpStatusCode)200 || response.StatusCode >= (HttpStatusCode)300)
|
||||||
@@ -72,14 +70,14 @@ namespace Discord.Net.Queue
|
|||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
Debug.WriteLine($"[{id}] (!) 429 [Global]");
|
Debug.WriteLine($"[{id}] (!) 429 [Global]");
|
||||||
#endif
|
#endif
|
||||||
_queue.PauseGlobal(info, lag);
|
_queue.PauseGlobal(info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
Debug.WriteLine($"[{id}] (!) 429");
|
Debug.WriteLine($"[{id}] (!) 429");
|
||||||
#endif
|
#endif
|
||||||
UpdateRateLimit(id, request, info, lag, true);
|
UpdateRateLimit(id, request, info, true);
|
||||||
}
|
}
|
||||||
await _queue.RaiseRateLimitTriggered(Id, info).ConfigureAwait(false);
|
await _queue.RaiseRateLimitTriggered(Id, info).ConfigureAwait(false);
|
||||||
continue; //Retry
|
continue; //Retry
|
||||||
@@ -92,6 +90,7 @@ namespace Discord.Net.Queue
|
|||||||
|
|
||||||
continue; //Retry
|
continue; //Retry
|
||||||
default:
|
default:
|
||||||
|
int? code = null;
|
||||||
string reason = null;
|
string reason = null;
|
||||||
if (response.Stream != null)
|
if (response.Stream != null)
|
||||||
{
|
{
|
||||||
@@ -101,12 +100,13 @@ namespace Discord.Net.Queue
|
|||||||
using (var jsonReader = new JsonTextReader(reader))
|
using (var jsonReader = new JsonTextReader(reader))
|
||||||
{
|
{
|
||||||
var json = JToken.Load(jsonReader);
|
var json = JToken.Load(jsonReader);
|
||||||
reason = json.Value<string>("message");
|
try { code = json.Value<int>("code"); } catch { };
|
||||||
|
try { reason = json.Value<string>("message"); } catch { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
throw new HttpException(response.StatusCode, reason);
|
throw new HttpException(response.StatusCode, code, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -142,7 +142,7 @@ namespace Discord.Net.Queue
|
|||||||
}*/
|
}*/
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
UpdateRateLimit(id, request, info, lag, false);
|
UpdateRateLimit(id, request, info, false);
|
||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
Debug.WriteLine($"[{id}] Stop");
|
Debug.WriteLine($"[{id}] Stop");
|
||||||
#endif
|
#endif
|
||||||
@@ -214,7 +214,7 @@ namespace Discord.Net.Queue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateRateLimit(int id, RestRequest request, RateLimitInfo info, TimeSpan lag, bool is429)
|
private void UpdateRateLimit(int id, RestRequest request, RateLimitInfo info, bool is429)
|
||||||
{
|
{
|
||||||
if (WindowCount == 0)
|
if (WindowCount == 0)
|
||||||
return;
|
return;
|
||||||
@@ -250,10 +250,10 @@ namespace Discord.Net.Queue
|
|||||||
}
|
}
|
||||||
else if (info.Reset.HasValue)
|
else if (info.Reset.HasValue)
|
||||||
{
|
{
|
||||||
resetTick = info.Reset.Value.AddSeconds(/*1.0 +*/ lag.TotalSeconds);
|
resetTick = info.Reset.Value.AddSeconds(info.Lag?.TotalSeconds ?? 1.0);
|
||||||
int diff = (int)(resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds;
|
int diff = (int)(resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds;
|
||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {lag.TotalMilliseconds} ms lag)");
|
Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {info.Lag?.TotalMilliseconds} ms lag)");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (request.Options.IsClientBucket && request.Options.BucketId != null)
|
else if (request.Options.IsClientBucket && request.Options.BucketId != null)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Discord.Net
|
|||||||
public int? Remaining { get; }
|
public int? Remaining { get; }
|
||||||
public int? RetryAfter { get; }
|
public int? RetryAfter { get; }
|
||||||
public DateTimeOffset? Reset { get; }
|
public DateTimeOffset? Reset { get; }
|
||||||
|
public TimeSpan? Lag { get; }
|
||||||
|
|
||||||
internal RateLimitInfo(Dictionary<string, string> headers)
|
internal RateLimitInfo(Dictionary<string, string> headers)
|
||||||
{
|
{
|
||||||
@@ -17,8 +18,11 @@ namespace Discord.Net
|
|||||||
IsGlobal = headers.TryGetValue("X-RateLimit-Global", out temp) ? bool.Parse(temp) : false;
|
IsGlobal = headers.TryGetValue("X-RateLimit-Global", out temp) ? bool.Parse(temp) : false;
|
||||||
Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) ? int.Parse(temp) : (int?)null;
|
Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) ? int.Parse(temp) : (int?)null;
|
||||||
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) ? int.Parse(temp) : (int?)null;
|
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) ? int.Parse(temp) : (int?)null;
|
||||||
Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) ? DateTimeUtils.FromUnixSeconds(int.Parse(temp)) : (DateTimeOffset?)null;
|
Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) ?
|
||||||
|
DateTimeUtils.FromUnixSeconds(int.Parse(temp)) : (DateTimeOffset?)null;
|
||||||
RetryAfter = headers.TryGetValue("Retry-After", out temp) ? int.Parse(temp) : (int?)null;
|
RetryAfter = headers.TryGetValue("Retry-After", out temp) ? int.Parse(temp) : (int?)null;
|
||||||
|
Lag = headers.TryGetValue("Date", out temp) ?
|
||||||
|
DateTimeOffset.UtcNow - DateTimeOffset.Parse(temp) : (TimeSpan?)null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user