debugcsharpMinor
AggregateException handling
Viewed 0 times
aggregateexceptionhandlingstackoverflow
Problem
How do you handle
These methods are defined on
```
public static class AggregateExceptionExtensions
{
public static AggregateException Handle(
this AggregateException source, Action handler)
where TEx : Exception
{
var exceptions = source.Flatten().InnerExceptions.OfType();
var handlerExceptions = new List();
foreach (var exception in exceptions)
try
{
handler(exception);
}
catch (Exception ex)
{
handlerExceptions.Add(ex);
}
return new AggregateException(source.InnerExceptions
.Except(exceptions)
.Concat(handlerExceptions));
}
public static AggregateExcept
AggregateException? It is really useful in many TPL or business scenarios, but handling is a real pain. I defined the following three extensions to help myself a little bit. They can be used this way:try
{
throw new AggregateException(
new ArgumentException(),
new DivideByZeroException());
}
catch (AggregateException aex)
{
aex
.Handle((ArgumentException ex) =>
{
Console.WriteLine(ex.Message);
})
.Handle((DivideByZeroException ex) =>
{
Console.WriteLine(ex.Message);
throw ex;
})
.Throw()
.Throw()
.ThrowIfNonEmpty();
}These methods are defined on
AggregateException and return AggregateException so they can be chained.Handle invokes parameter delegate once per each inner exception instance of a specified type and returns a new copy of AggregateException without those handled exceptions. An optional exception being thrown in the delegate will be added to the resulting AggregateException.Throw method tries to find a first inner exception instance of specified type and throws it if found. You can chain them to decide on priority.ThrowIfNonEmpty extends an AggregateException to throw it when InnerExceptions collection is not empty.```
public static class AggregateExceptionExtensions
{
public static AggregateException Handle(
this AggregateException source, Action handler)
where TEx : Exception
{
var exceptions = source.Flatten().InnerExceptions.OfType();
var handlerExceptions = new List();
foreach (var exception in exceptions)
try
{
handler(exception);
}
catch (Exception ex)
{
handlerExceptions.Add(ex);
}
return new AggregateException(source.InnerExceptions
.Except(exceptions)
.Concat(handlerExceptions));
}
public static AggregateExcept
Solution
I don't think it's a good idea to rethrow only the first/single exception of a particular type. Often, when done right ;-) each exception may contain different data about what went wrong, like entity validation errors may happen for multiple entities or mutliple files may not have been found etc. If you pick only the first one you won't know about the rest and you'll app crashes agian next time.
The
Additionaly I would change the
so that I can for example log it and still be able to say I didn't handle it by returning
The
Handle and the ThrowIfNonEmpty are fine but Throw is very harmful.Additionaly I would change the
Handle to be Func:public static AggregateException Handle(
this AggregateException source, Func handler)
where TEx : Exception
{
var exceptions = source.Flatten().InnerExceptions.OfType();
var handlerExceptions = new List();
foreach (var exception in exceptions)
{
try
{
if (!handler(exception))
{
handlerExceptions.Add(exception);
}
}
catch (Exception ex)
{
handlerExceptions.Add(ex);
}
}
return new AggregateException(source.InnerExceptions
.Except(exceptions)
.Concat(handlerExceptions));
}so that I can for example log it and still be able to say I didn't handle it by returning
false..Handle((ArgumentException ex) =>
{
Console.WriteLine(ex.Message);
return false;
})Code Snippets
public static AggregateException Handle<TEx>(
this AggregateException source, Func<TEx, bool> handler)
where TEx : Exception
{
var exceptions = source.Flatten().InnerExceptions.OfType<TEx>();
var handlerExceptions = new List<Exception>();
foreach (var exception in exceptions)
{
try
{
if (!handler(exception))
{
handlerExceptions.Add(exception);
}
}
catch (Exception ex)
{
handlerExceptions.Add(ex);
}
}
return new AggregateException(source.InnerExceptions
.Except(exceptions)
.Concat(handlerExceptions));
}.Handle((ArgumentException ex) =>
{
Console.WriteLine(ex.Message);
return false;
})Context
StackExchange Code Review Q#120503, answer score: 2
Revisions (0)
No revisions yet.