{"action":"created","issue":{"url":"https://api.github.com/repos/App-vNext/Polly/issues/266","repository_url":"https://api.github.com/repos/App-vNext/Polly","labels_url":"https://api.github.com/repos/App-vNext/Polly/issues/266/labels{/name}","comments_url":"https://api.github.com/repos/App-vNext/Polly/issues/266/comments","events_url":"https://api.github.com/repos/App-vNext/Polly/issues/266/events","html_url":"https://github.com/App-vNext/Polly/issues/266","id":240226267,"number":266,"title":"question: Retry policy with action upon failure","user":{"login":"grokky1","id":25845408,"avatar_url":"https://avatars0.githubusercontent.com/u/25845408?v=3","gravatar_id":"","url":"https://api.github.com/users/grokky1","html_url":"https://github.com/grokky1","followers_url":"https://api.github.com/users/grokky1/followers","following_url":"https://api.github.com/users/grokky1/following{/other_user}","gists_url":"https://api.github.com/users/grokky1/gists{/gist_id}","starred_url":"https://api.github.com/users/grokky1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grokky1/subscriptions","organizations_url":"https://api.github.com/users/grokky1/orgs","repos_url":"https://api.github.com/users/grokky1/repos","events_url":"https://api.github.com/users/grokky1/events{/privacy}","received_events_url":"https://api.github.com/users/grokky1/received_events","type":"User","site_admin":false},"labels":[{"id":38476909,"url":"https://api.github.com/repos/App-vNext/Polly/labels/question","name":"question","color":"cc317c","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2017-07-03T17:03:31Z","updated_at":"2017-07-04T21:12:55Z","closed_at":null,"body":"New user here, loving this library so far... kudos!\r\n\r\nI'm using a delay and retry policy, something like this:\r\n\r\n````csharp\r\nvar policy = Policy\r\n  .Handle<Exception>()\r\n  .WaitAndRetry(10, sleep, () => {\r\n    // do something after retry failure\r\n  });\r\nvar policyResult = await policy.ExecuteAndCaptureAsync(() => DoSomething());\r\n````\r\n\r\nWhat I need to do is log before each retry, and log after the last failure. For the before case, there is the `onRetry` delegate... but what about the after case?\r\n\r\nI haven't found anything, so I append this to the code above:\r\n````csharp\r\nif (policyResult.Outcome == OutcomeType.Failure) {\r\n  // do something after last failure\r\n}\r\n````\r\n\r\nThis works, but it isn't reusable. I want to be able to define a `Policy` instance, and pass it around.\r\n\r\nIs there an overload I've missed, or some way to do this? It would have been awesome if the library had a callback for the after case, something like `\"onLastFailure\"`."},"comment":{"url":"https://api.github.com/repos/App-vNext/Polly/issues/comments/312956007","html_url":"https://github.com/App-vNext/Polly/issues/266#issuecomment-312956007","issue_url":"https://api.github.com/repos/App-vNext/Polly/issues/266","id":312956007,"user":{"login":"reisenberger","id":9608723,"avatar_url":"https://avatars2.githubusercontent.com/u/9608723?v=3","gravatar_id":"","url":"https://api.github.com/users/reisenberger","html_url":"https://github.com/reisenberger","followers_url":"https://api.github.com/users/reisenberger/followers","following_url":"https://api.github.com/users/reisenberger/following{/other_user}","gists_url":"https://api.github.com/users/reisenberger/gists{/gist_id}","starred_url":"https://api.github.com/users/reisenberger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reisenberger/subscriptions","organizations_url":"https://api.github.com/users/reisenberger/orgs","repos_url":"https://api.github.com/users/reisenberger/repos","events_url":"https://api.github.com/users/reisenberger/events{/privacy}","received_events_url":"https://api.github.com/users/reisenberger/received_events","type":"User","site_admin":false},"created_at":"2017-07-04T21:12:55Z","updated_at":"2017-07-04T21:12:55Z","body":"Hi @grokky1 !   We'll aim to fix up the use of `ExecuteAndCapture/Async()` with `PolicyWrap`; I've raised #267, with a proposal.\r\n\r\nRe:\r\n\r\n>I don't know whether the policy passed/failed [with `ExecuteAndCapture/Async()`], because there is nothing similar to `PolicyResult.Outcome`. \r\n\r\n`ExecuteAndCapture/Async()` is [just a try-catch, -> set result object](https://github.com/App-vNext/Polly/blob/75456beee1c4e25b88ab34057434bdc1eec30480/src/Polly.Shared/PolicyAsync.cs#L1130-L1138).  With `ExecuteAsync()` rather than `ExecuteAndCaptureAsync()`, you just have any final exception thrown.\r\n\r\nSo: If `policy` in `await policy.ExecuteAsync(() => DoSomething());` were just a retry policy, and all retries fail, the retry policy [will propagate the final exception](https://github.com/App-vNext/Polly/wiki/Retry#how-polly-retry-works) - so you'd know the retry policy failed by that exception being thrown (and need to `try/catch` for it).\r\n\r\nIf following the `PolicyWrap` pattern earlier in the thread, you'd typically use the `FallbackPolicy` to absorb that final exception from the inner retry policy (and take whatever compensating action you deem), so you'd know the retries failed from the `FallbackPolicy` kicking in.  Here's a fuller example commenting that, and demonstrating a common `LogPolicyExceptionAsync(exc)` delegate:\r\n\r\n```\r\nvar retryPolicy = Policy\r\n  .Handle<Exception>()\r\n  .WaitAndRetryAsync(10, sleep, onRetryAsync: async (exc, span) => LogPolicyExceptionAsync(exc));\r\nvar fallbackPolicy = Policy\r\n  .Handle<Exception>()\r\n  .FallbackAsync(fallbackAction: async cancellationToken => \r\n     {\r\n         // You will know all retries failed because your code hits here.\r\n         // Do whatever desired to substitute for/compensate-for-failure-of executions through the policy.  \r\n     },\r\n     onFallbackAsync: async exc => LogPolicyExceptionAsync(exc));\r\nvar retryWithFallback = fallbackPolicy.WrapAsync(retryPolicy);\r\n\r\n// elsewhere:\r\nawait retryWithFallback.ExecuteAsync(() => DoSomethingAsync())\r\n```"}}
{"actor":{"display_login":"reisenberger"}}