简体   繁体   English

制定政策

[英]Hooking up Polly Policy

Can someone advice why my Policy handle is not handling my WebException error when I know for a fact that the code hit a WebException for a 429 problem? 当我知道代码因429问题而碰到WebException时,有人可以建议我的Policy句柄为什么不处理WebException错误吗? I've been researching this for a while now and need some help. 我已经研究了一段时间,需要一些帮助。

This is my Polly Policy: 这是我的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); }); 

I'm using it like this: 我正在这样使用它:

 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;
    }

When I run the code, I can see that it trigger the WebException but the Policy is not being called. 运行代码时,我可以看到它触发了WebException,但是没有调用Policy。 Please help. 请帮忙。

Your try {} catch {} is swallowing the thrown exceptions before the Polly policy has the chance to handle them. 您的try {} catch {}在Polly政策有机会处理它们之前吞下了抛出的异常。 Where you have: 您在哪里:

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

Use: 采用:

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

Explanation: When a catch clause catches an exception and does not rethrow it, the exception is not propagated outside the catch block when the catch block completes. 说明:当catch子句捕获异常并且不重新抛出该异常时,该catch块完成时该异常不会传播到catch块之外。 The catch block swallows the exception. catch块吞下了异常。

For Polly to handle an exception, the exception needs to be propagated out of the delegate you pass to policy.Execute(() => ) , so that it is thrown back on to the policy, which then handles it. 为了让Polly处理异常,需要将异常传播到传递给policy.Execute(() => )的委托policy.Execute(() => ) ,以便将其重新放回策略,然后由该策略进行处理。


EDIT: The above answer intentionally demonstrates the minimum that needs to be changed from the posted code, to make the Polly policy handle the exception. 编辑:上面的答案有意演示了需要从发布的代码进行更改,以使Polly策略处理异常的最小值。 As Cyrus suggested in the comments, if the sole use of the try / catch is for some extra logging, you can instead do that in the onRetry clause of the Polly policy, and remove the try / catch altogether. 正如Cyrus在评论中建议的那样,如果try / catch的唯一用途是用于一些额外的日志记录,则可以改为在Polly策略的onRetry子句中这样做,然后完全删除try / catch


SECOND EDIT: If the concern is that the Polly policy still eventually rethrows the WebException if all retries fail: this is intentional ; 第二个编辑:如果担心的是,波利政策最终还是重新抛出WebException如果所有试失败: 这是故意的 ; RetryPolicy signals that all retries have been made without success by rethrowing the final exception. RetryPolicy通过抛出最终异常来发出所有重试均未成功的信号。

If you wish to trap that final exception without having to add your own further try / catch , Polly .ExecuteAndCapture(...) can be used for this. 如果您希望捕获最后的异常而不必添加自己的进一步try / catch ,则可以使用Polly .ExecuteAndCapture(...)

I appreciate all the help guys. 我感谢所有帮助人员。 The problem was that the WebException is a 429 error. 问题是WebException是429错误。 If I don't put the try catch methods in there, my code will blow up. 如果我不把try catch方法放在那里,我的代码就会崩溃。 So what I end up doing is extend the policy a bit more to look like this. 因此,我最终要做的是将策略扩展得更多。

>    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);
                });
        }

Then I return the response from the API WebRequest and Polly policy is now able to consume the error thrown and retry. 然后,我从API WebRequest返回响应,并且Polly策略现在可以使用抛出的错误并重试。 Which look something like this at the end. 最终看起来像这样。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM