Sturla
Sturla

Reputation: 3626

Best retry policy for Refit ApiException?

I´m using both Refit and Polly to call to restful API´s and I´m wondering what the retry (if any) policy for Refits ApiException should be?

public static PolicyWrap MyRetryPolicy()
{
        // Try few times with little more time between... maybe the 
        // connection issue gets resolved
        var wireServerNetworkIssue = Policy.Handle<WebException>() 
                                    .WaitAndRetryAsync(new[] {
                                    TimeSpan.FromSeconds(1),
                                    TimeSpan.FromSeconds(2),
                                    TimeSpan.FromSeconds(4)});
        var policyList = new List<Policy>();

        // But if there is something wrong with the api
        // I should do what (if general)?
        var api = Policy.Handle<ApiException>()
                  .RetryAsync(1, onRetry: async (exception, i) =>
                  {
                       await Task.Run(() =>
                       {
                           // What would be normal to do here?
                           // Try again or do some circuit braking?
                       });
                  });

        policyList.Add(wireServerNetworkIssue);
        policyList.Add(api);

        return Policy.Wrap(policyList.ToArray());
}

And then I use it like this

try
{
    myApi = RestService.For<MyApi>("api base url");
    var policyWrapper = Policies.Policies.MyRetryPolicyWrapper();
    var response  = await policy.ExecuteAsync(() => myApi.SendReceiptAsync(receipt));
}
catch (ApiException apiEx)
{
  //Do something if the retry policy did´t fix it.
}
catch (WebException webEx)
{
  //Do something if the retry policy did´t fix it.
}

The Question

What would be a normal retry policy for ApiExceptions? Would you just circuit brake or under what general circumstances would you do something to recover?

The answer is probably "it depends on what your service returns" but I just have to ask.

Upvotes: 4

Views: 9513

Answers (1)

mountain traveller
mountain traveller

Reputation: 8156

If the ApiExceptions returned contain meaningful HttpStatusCode StatusCode properties, you could certainly choose which of those StatusCodes merit a retry; the Polly readme suggests:

int[] httpStatusCodesWorthRetrying = {408, 500, 502, 503, 504}; 

For ApiExceptions specific to the API called, only knowledge of what those API-specific errors represent, can guide whether to retry them.

If you choose to circuit-break on too many exceptions of some kind, that should be achieved by wrapping a circuit-breaker into your PolicyWrap, rather than within the onRetry delegate of the retry policy. Polly discusses 'Why circuit-break?' here, and links to a number of other circuit-breaker blog posts at the foot of the readme circuit-breaker section.

Upvotes: 2

Related Questions