Handling InnerExceptions and AggregateExceptions - App-vNext/Polly GitHub Wiki
Note
This documentation describes the previous Polly v7 API. If you are using the new v8 API, please refer to pollydocs.org.
Polly v5.6.0 adds new syntax to natively handle InnerExceptions, both of ordinary exceptions and of AggregateException.
.HandleInner<TException>() // matches any inner exception of type TException
.HandleInner<TException>(Func<TException, bool>) // matches an inner TException matching the Func
.OrInner<TException>() // as above, 'Or' syntax
.OrInner<TException>(Func<TException, bool>) // as above, 'Or' syntaxHandling inner exceptions can be freely combined with handling non-inner exceptions and with handling returned result values.
.HandleInner<TException>() matches exceptions at both the top-level (as .Handle<>()), and any inner exceptions.
When the operation executed through the policy throws an AggregateException, the policy will additionally check the flattened InnerExceptions for matches.
When the operation executed through the policy throws an ordinary (non-aggregate) Exception, the policy will additionally recursively check any InnerExceptions for matches.
When a .HandleInner<TException>(...) clause matches an inner exception, for convenience, the policy substitutes the matched inner exception (rather than supplying the wrapping outer exception) in any place that communicates matched exceptions to calling code.
| Feature | Code element that will be passed the inner exception |
|---|---|
| Retry policy family | onRetry |
| Circuit-breaker policy family |
onBreakcircuitbreaker.LastExceptionthe exception rethrown |
| Fallback policy |
onFallbackfallbackAction
|
| ExecuteAndCapture | PolicyResult.FinalException |
This prevents user code having to duplicate the logic to extract the inner exception, and allows policy event hooks (eg onRetry, onBreak) to be written in a uniform manner whether the given exception is trapped as a top-level or inner exception.
If it is desired to retain the original AggregateException information (rather than substitute the matched inner exception) this can still be achieved, by handling the AggregateException directly:
.Handle<AggregateException>(ae => /* etc */)