I'd like to use Polly to handle the result of an HTTP API call I need to make. I have the policy defined as:
var r = await Policy
.HandleResult<DescribeApplicationVersionsResponse>(x => x.ApplicationVersions[0]?.Status != ApplicationVersionStatus.Processed)
.WaitAndRetryAsync(10, retryAttempt => TimeSpan.FromSeconds(1), onRetry: (describeResponse, timeSpan, context) => {
Console.WriteLine($"Application version was '{describeResponse.Result.ApplicationVersions[0].Status}', retrying in {timeSpan}");
})
.ExecuteAsync(() =>
BeanstalkClient.DescribeApplicationVersionsAsync(describeApplicationVersionRequest)
);
If the policy never succeeds (i.e., the result criteria is never met and the retry limit has been passed) I'd like to throw an exception as my application can't continue.
Is it possible to define that through the Polly policy builder extension methods?
If all retries configured for a Polly retry policy are exhausted without the executed delegate succeeding, the retry policy rethrows the exception for which no more retries are permitted, as documented in the Polly readme (foot of retry section) and Polly retry wiki.
If you want to throw a different exception from the one propagating from the delegate, you could do any of:
try
/catch
and throw something else; (or).ExecuteAndCapture(...)
to capture, then check, the final execution result, and throw your own custom exception; (or)PolicyWrap
to wrap a FallbackPolicy
outside the retry policy, and in the FallbackPolicy, handle the exception from retries-failing and in the fallback action, rethrow a different custom exception.EDITED: To reflect the fact that the OP's original policy was handling results, not exceptions. An approach using FallbackPolicy
with PolicyWrap
could be as follows:
var retry = Policy
.HandleResult<DescribeApplicationVersionsResponse>(x => x.ApplicationVersions[0]?.Status != ApplicationVersionStatus.Processed)
.WaitAndRetryAsync(10, retryAttempt => TimeSpan.FromSeconds(1), onRetry: (describeResponse, timeSpan, context) => {
Console.WriteLine($"Application version was '{describeResponse.Result.ApplicationVersions[0].Status}', retrying in {timeSpan}");
});
var fallback = Policy
.HandleResult<DescribeApplicationVersionsResponse>(x => x.ApplicationVersions[0]?.Status != ApplicationVersionStatus.Processed) // Probably worth factoring the predicate out into a method so that it is only stated once.
.FallbackAsync(async () => { throw new ReplacementException(); });
var r = await fallback.WrapAsync(retry)
.ExecuteAsync(() =>
BeanstalkClient.DescribeApplicationVersionsAsync(describeApplicationVersionRequest)
);