Пример #1
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var obj = JObject.Load(reader);
            var err = new API.DiscordError();


            var result = obj.GetValue("errors", StringComparison.OrdinalIgnoreCase);

            result?.Parent.Remove();

            // Populate the remaining properties.
            using (var subReader = obj.CreateReader())
            {
                serializer.Populate(subReader, err);
            }

            if (result != null)
            {
                var innerReader = result.CreateReader();

                var errors = ReadErrors(innerReader);
                err.Errors = errors.ToArray();
            }

            return(err);
        }
Пример #2
0
        public async Task <Stream> SendAsync(RestRequest request)
        {
            int id = Interlocked.Increment(ref nextId);

#if DEBUG_LIMITS
            Debug.WriteLine($"[{id}] Start");
#endif
            LastAttemptAt = DateTimeOffset.UtcNow;
            while (true)
            {
                await _queue.EnterGlobalAsync(id, request).ConfigureAwait(false);
                await EnterAsync(id, request).ConfigureAwait(false);

                if (_redirectBucket != null)
                {
                    return(await _redirectBucket.SendAsync(request));
                }

#if DEBUG_LIMITS
                Debug.WriteLine($"[{id}] Sending...");
#endif
                RateLimitInfo info = default(RateLimitInfo);
                try
                {
                    var response = await request.SendAsync().ConfigureAwait(false);

                    info = new RateLimitInfo(response.Headers, request.Endpoint);

                    request.Options.ExecuteRatelimitCallback(info);

                    if (response.StatusCode < (HttpStatusCode)200 || response.StatusCode >= (HttpStatusCode)300)
                    {
                        switch (response.StatusCode)
                        {
                        case (HttpStatusCode)429:
                            if (info.IsGlobal)
                            {
#if DEBUG_LIMITS
                                Debug.WriteLine($"[{id}] (!) 429 [Global]");
#endif
                                _queue.PauseGlobal(info);
                            }
                            else
                            {
#if DEBUG_LIMITS
                                Debug.WriteLine($"[{id}] (!) 429");
#endif
                                UpdateRateLimit(id, request, info, true, body: response.Stream);
                            }
                            await _queue.RaiseRateLimitTriggered(Id, info, $"{request.Method} {request.Endpoint}").ConfigureAwait(false);

                            continue;                   //Retry

                        case HttpStatusCode.BadGateway: //502
#if DEBUG_LIMITS
                            Debug.WriteLine($"[{id}] (!) 502");
#endif
                            if ((request.Options.RetryMode & RetryMode.Retry502) == 0)
                            {
                                throw new HttpException(HttpStatusCode.BadGateway, request, null);
                            }

                            continue;     //Retry

                        default:
                            API.DiscordError error = null;
                            if (response.Stream != null)
                            {
                                try
                                {
                                    using var reader     = new StreamReader(response.Stream);
                                    using var jsonReader = new JsonTextReader(reader);

                                    error = Discord.Rest.DiscordRestClient.Serializer.Deserialize <API.DiscordError>(jsonReader);
                                }
                                catch { }
                            }
                            throw new HttpException(
                                      response.StatusCode,
                                      request,
                                      error?.Code,
                                      error?.Message,
                                      error?.Errors.IsSpecified == true ?
                                      error.Errors.Value.Select(x => new DiscordJsonError(x.Name.GetValueOrDefault("root"), x.Errors.Select(y => new DiscordError(y.Code, y.Message)).ToArray())).ToArray() :
                                      null
                                      );
                        }
                    }
                    else
                    {
#if DEBUG_LIMITS
                        Debug.WriteLine($"[{id}] Success");
#endif
                        return(response.Stream);
                    }
                }
                //catch (HttpException) { throw; } //Pass through
                catch (TimeoutException)
                {
#if DEBUG_LIMITS
                    Debug.WriteLine($"[{id}] Timeout");
#endif
                    if ((request.Options.RetryMode & RetryMode.RetryTimeouts) == 0)
                    {
                        throw;
                    }

                    await Task.Delay(500).ConfigureAwait(false);

                    continue; //Retry
                }

                /*catch (Exception)
                 * {
                 #if DEBUG_LIMITS
                 *  Debug.WriteLine($"[{id}] Error");
                 #endif
                 *  if ((request.Options.RetryMode & RetryMode.RetryErrors) == 0)
                 *      throw;
                 *
                 *  await Task.Delay(500);
                 *  continue; //Retry
                 * }*/
                finally
                {
                    UpdateRateLimit(id, request, info, false);
#if DEBUG_LIMITS
                    Debug.WriteLine($"[{id}] Stop");
#endif
                }
            }
        }