Соединение Политики Полли - PullRequest
0 голосов
/ 15 декабря 2018

Может кто-нибудь посоветовать, почему мой дескриптор политики не обрабатывает мою ошибку WebException, когда я точно знаю, что код столкнулся с WebException для проблемы 429?Я изучал это некоторое время и мне нужна помощь.

Это моя политика Polly:

return Policy.Handle<WebException>()
            .WaitAndRetry(15, // We can also do this with WaitAndRetryForever... but chose WaitAndRetry this time.
            attempt => TimeSpan.FromSeconds(0.1 * Math.Pow(2, attempt)), // Back off!  2, 4, 8, 16 etc times 1/4-second
            (exception, calculatedWaitDuration) =>  // Capture some info for logging! if needed
            {
                // This is your new exception handler! 
                Debug.WriteLine("Retry count: " + retries++);
                Debug.WriteLine("Wait Duration: " + calculatedWaitDuration);
            });

Я использую это так:

 webResponseWaitRetryPolicy.Execute(() =>
        {
            // Make a request and get a response
            UriBuilder builder = new UriBuilder(options.BaseUrl);
                builder.Port = -1;
                var query = HttpUtility.ParseQueryString(builder.Query);
                /// handle parameters
                query["client_key"] = options.ClientKey;
                query["model_id"] = model;
                query["image_url"] = imageUrl;

                builder.Query = query.ToString();
                string url = builder.ToString();
                string content = string.Empty;

                Result objResult;
               HttpWebResponse response = null;


                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.AutomaticDecompression = DecompressionMethods.GZip;
                try
                {
                   response = (HttpWebResponse)request.GetResponse();
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (Stream stream = response.GetResponseStream())
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            content = reader.ReadToEnd();
                        }

                        objResult = JsonConvert.DeserializeObject<Result>(content);


                }
                catch(WebException ex)
                {
                    eventualFailures++; 
                    Debug.WriteLine("Failure: " + eventualFailures);


                }
            });

        return objResult;
    }

Когда я запускаю код, я вижу, что он вызывает исключение WebException, но политика не вызывается.Пожалуйста, помогите.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Я ценю всю помощь, ребята.Проблема была в том, что WebException - это ошибка 429.Если я не добавлю туда методы try catch, мой код взорвется.Поэтому я в конечном итоге расширяю политику так, чтобы она выглядела следующим образом.

>    public static Policy<HttpWebResponse> Get429WebResponseWaitRetryPolicy()
        {
            //Retries policy
            return Policy.Handle<WebException>().OrResult<HttpWebResponse>(r => r == null)
                .WaitAndRetry(15, // We can also do this with WaitAndRetryForever... but chose WaitAndRetry this time.
                attempt => TimeSpan.FromSeconds(0.1 * Math.Pow(2, attempt)), // Back off!  2, 4, 8, 16 etc times 1/4-second
                (exception, calculatedWaitDuration) =>  // Capture some info for logging! if needed
                {
                    // This is your new exception handler! 
                    Debug.WriteLine("Retry count: " + retries++);
                    Debug.WriteLine("Wait Duration: " + calculatedWaitDuration);
                });
        }

Затем я возвращаю ответ от API WebRequest, и политика Polly теперь может использовать выданную ошибку и повторить попытку.Который выглядит примерно так в конце.

Debug.WriteLine("Success: " + eventualSuccesses);
                    return response;
                }
                catch(WebException ex)
                {
                    eventualFailures++; 
                    Debug.WriteLine("Failure: " + eventualFailures);
                    return response;
                 }
0 голосов
/ 16 декабря 2018

Ваш try {} catch {} глотает выброшенные исключения, прежде чем политика Полли сможет их обработать.Где у вас есть:

try
{
    /* snip */
}
catch(WebException ex)
{
    eventualFailures++; 
    Debug.WriteLine("Failure: " + eventualFailures);
}

Использование:

try
{
    /* snip */
}
catch(WebException ex)
{
    eventualFailures++; 
    Debug.WriteLine("Failure: " + eventualFailures);
    throw;
}

Объяснение: Когда предложение catch перехватывает исключение и не перебрасывает его, исключение не распространяется за пределы catch блок, когда блок catch завершается.Блок catch поглощает исключение.

Чтобы Polly обработал исключение, исключение необходимо распространить из делегата, который вы передаете policy.Execute(() => ), чтобы он был возвращен в политику,который затем обрабатывает это.


РЕДАКТИРОВАТЬ: Приведенный выше ответ намеренно демонстрирует минимум, который необходимо изменить по сравнению с опубликованным кодом, чтобы политика Polly обработала исключение.Как Сайрус предложил в комментариях, если единственное использование try / catch предназначено для некоторой дополнительной регистрации, вы можете вместо этого сделать это в предложении onRetry политики Polly и удалить try / catch в целом.


ВТОРОЕ РЕДАКТИРОВАНИЕ: Если проблема заключается в том, что политика Полли все еще в конечном итоге отбрасывает WebException, если все попытки повторяются: это преднамеренно ;RetryPolicy сигнализирует о том, что все попытки были сделаны безуспешно, перебрасывая последнее исключение.

Если вы хотите перехватить это последнее исключение, не добавляя свое собственное try / catch, для этого можно использовать Polly .ExecuteAndCapture(...).

...