How to Unwrap an AggregateException Thrown by AWS Lambda

Update 1st April 2020:
This is now only valid for .NET Core 2.1 functions.
The default behaviour for .NET Core 3.1 functions is the same as when UNWRAP_AGGREGATE_EXCEPTIONS was set to true.
my new post for more.

If you’ve written a .NET Lambda function which calls async code and returns either Task or Task<T>, you’ve probably seen an AggregateException which wraps the real exception.

This example comes from the handler below which calls an asnyc method that always throws a FormatException.

The AggregateException can be unwrapped, though. When AWS added .NET Core 2.1 support to Lambda, they also added an undocumented feature toggle. The only real mention of it is by the AWS .NET team on Reddit.

When the UNWRAP_AGGREGATE_EXCEPTIONS environment variable is set to 1 or true, Lambda will call GetAwaiter().GetResult() instead of using theResult property.

Note that this only works if your method returns Task or Task<T>.

This causes the first exception thrown to be returned instead of an AggregateException.

To avoid compatibility issues, this is opt-in via the environment variable. However, in the Reddit comment, the team says they plan to make it the default behaviour in future versions. I think they’ll keep the toggle, though, because it can be useful.

The reason you get an AggregateException is that a single Task can represent multiple parallel tasks, each of which can throw an exception. You’ll most often see this when using Task.WaitAll or Task.WhenAll.

This convoluted example runs three tasks in parallel, two of which throw an exception.

Setting the UNWRAP_AGGREGATE_EXCEPTIONS environment variable gets us back to just the FormatException which was thrown first. In the future, you’ll need to toggle unwrapping exceptions off when you want to see every exception.

For more like this, please follow me on Medium and Twitter.

Principal Engineer @ Just Eat | AWS Community Builder

Principal Engineer @ Just Eat | AWS Community Builder