louthy/language-ext · error · AggregateException
AggregateException from collected inner errors
Error message
AggregateException from collected inner errors
What it means
AsyncEnumerableEx.Merge aggregates the exceptions thrown by the merged source sequences; when any inner stream errors, the merge enumerates errors and throws a single AggregateException containing all collected inner errors at line 110. This is the library's way of reporting multiple concurrent stream failures from one Merge call. The real causes are the inner exceptions — inspect AggregateException.InnerExceptions.
Solutions
- Inspect ex.InnerExceptions on the AggregateException to handle each underlying failure
- Wrap the Merge consumption in try/catch (AggregateException) and decide per-inner-error whether to retry or drop
- Retry individual failing sources with backoff before merging, so Merge itself stays error-free
- Use error-tolerant sources (catch inside each source stream and yield a sentinel) so one failure doesn't fail the merge
Example fix
// before
await foreach (var x in AsyncEnumerableEx.Merge(srcA, srcB))
Process(x); // throws AggregateException if either source fails
// after
try
{
await foreach (var x in AsyncEnumerableEx.Merge(srcA, srcB))
Process(x);
}
catch (AggregateException agg)
{
foreach (var inner in agg.InnerExceptions)
Log(inner); // handle/retry each failing source individually
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight each source with a guard var safeA = srcA.Catch(ex => AsyncEnumerable.Empty<T>()); var safeB = srcB.Catch(ex => AsyncEnumerable.Empty<T>()); var merged = AsyncEnumerableEx.Merge(safeA, safeB);
Type guard
static bool HasInnerErrors(AggregateException agg) => agg.InnerExceptions.Count > 0;
Try / catch
try { await foreach (var x in merged) Process(x); }
catch (AggregateException agg)
{
foreach (var inner in agg.InnerExceptions)
HandleSourceError(inner); // retry/log per failing source
} Prevention
- Wrap each merged source with .Catch so one failure doesn't kill the merge
- Always catch AggregateException (not Exception) around Merge consumption
- Add retry-with-backoff to flaky inner sources before merging
- Log InnerExceptions individually to identify which source failed
When it happens
Trigger: Calling Merge (or Merge with a concurrency limit) where one or more of the merged IAsyncEnumerable sources throws while the merged sequence is being consumed; all inner errors are gathered and rethrown together as AggregateException.
Common situations: Merging several HTTP/stream/event sources where some fail mid-enumeration (network faults, upstream 5xx, canceled subscriptions); a partially failing fan-in pipeline; consuming Merge output without handling AggregateException.
Related errors
- Nil iterator has no head
- OperationCanceledException
- Ord attribute should have a struct type that derives from…
- Hashable attribute should have a struct type that derives…
- Don't use Equals - use either RecordType
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/b53385e72f45666e.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Utility/AsyncEnumerableEx.cs:110
{
await enumerator.DisposeAsync().ConfigureAwait(false);
}
}
}
catch (Exception ex)
{
if (errors == null)
{
errors = new List<Exception>();
}
errors.Add(ex);
}
}
if (errors != null)
{
throw new AggregateException(errors);
}
}
}
}
/// <summary>
/// Merges elements from all inner async-enumerable sequences into a single async-enumerable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequences.</typeparam>
/// <param name="sources">Async-enumerable sequence of inner async-enumerable sequences.</param>
/// <returns>The async-enumerable sequence that merges the elements of the inner sequences.</returns>
/// <exception cref="ArgumentNullException"><paramref name="sources"/> is null.</exception>
public static IAsyncEnumerable<TSource> Merge<TSource>(
this IAsyncEnumerable<IAsyncEnumerable<TSource>> sources) =>
sources.SelectMany(source => source);
}
View on GitHub (pinned to 2f0e362824)