Polly currently does not offer any extra tooling for handling InnerExceptions of AggregateException.
InnerExceptions of AggregateException can currently be handled, by writing eg
.Handle<AggregateException>(ae => ae.Flatten().InnerExceptions.Any(ie => ie is ExceptionTypeIWantToHandle))
(and similar). But we have requests (1; 2; 3) for more in-built support.
AggregateException.InnerExceptionsMake the existing .Handle<TException>(...) syntax _automatically_ extend to find InnerExceptions of AggregateException which match.
_Advantages_: Most concise; least work for the developer.
_Disadvantages_:
.HandleInner<>(...)Add new explicit syntax .HandleInAggregate<TException>(...); or HandleInnerException<TException>(...).
_Advantages_:
(i) Anywhere the discussion mentions .Handle...(), assume that equivalent .Or...() syntax is also meant; and that all variants of .Handle() (eg also the variant with an extra bool predicate) are meant.
(ii) Matching would find recursively nested inner exceptions, using eg AggregateException.Flatten() or similar.
(iii) Where any other aspect of a Polly policy expressed a handled exception (for example PolicyResult.FinalException with .ExecuteAndCapture(...); or when the handled exception is passed to policy delegates like onRetry or onBreak; or when a measured exception is rethrown by CircuitBreaker), Polly would always passed the matched, unwrapped inner exception rather than the wrapping exception. [Caveat: .NET4.0 does not support ExceptionDispatchInfo and might lose stack trace info or require workround]
AggregateException wrapped both a matched exception and some other exception(s). Assumption (iii) above (promoting and returning the matched InnerException) would imply _discarding_ any other inner exceptions; these would _not_ be available to following code._Community views?_: does the advantage of (iii) outweigh the disadvantage of (iv)?
Observations:
AggregateException containing a single InnerException might be the more common scenario, from typical async/await usages; multiple InnerExceptions are more _usually_ connected with fork/join scenarios.
With either (a) or (b), it would still be possible to gain full access to the other InnerExceptions by handling the AggregateException directly using eg .Handle<AggregateException>(ae => ... ), in scenarios where (iv) was a concern. So there is a workround.
_Community views?_
Suggestions of different options / variations also welcome!
I believe that the .HandleInner<Exception>() syntax to a better option than implicit processing. As you mentioned, with it implicitly scanning inner exceptions it is a potentially breaking change for existing systems and I would be legitimately concerned about the performance impacts.
If implicit scanning were implemented, and the AggregateException wraps an AggregateException, what would be the expected behavior? By making the definition explicit, developers can extend their application's functionality as it suits them.
Ideally, the .HandleInner<Exception>() signature could have an overload which allows it to scan an exception's inner exception to a finite depth.
Another vote for .HandleInner<Exception>()
The following, IMHO, outweigh other considerations:
This feature is delivered in Polly v5.6.0 (will be released via nuget in next day or so).