When awaiting a faulted task (one that has an exception set), await
will rethrow the stored exception. If the stored exception is an AggregateException
I don't want to give up the practice to only catch the exceptions I expect. This leads me to the following extension method:
public static async Task NoSwallow(this Task task) where TException : Exception {
try {
await task;
} catch (TException) {
var unexpectedEx = task.Exception
.Flatten()
.InnerExceptions
.FirstOrDefault(ex => !(ex is TException));
if (unexpectedEx != null) {
throw new NotImplementedException(null, unexpectedEx);
} else {
throw task.Exception;
}
}
}
The consuming code could go like this:
try {
await Task.WhenAll(tasks).NoSwallow();
catch (AggregateException ex) {
HandleExceptions(ex);
}
A bone-headed exception will have the same effect as in synchronous world, even in case it is thrown concurrently with a MyException
by chance. The wrapping with NotImplementedException
helps to not loose the original stack trace.