Jef Claes

On software and life

15 May 2010

Exception handling in batch operations with the AggregateException

Doing batch operations and elegantly handling exceptions is a problem which every developer has faced before. In .NET 3.5 or older there is no out-of-the-box solution to handle exceptions in these types of scenarios, without being inconsistent to the normal flow of exception handling. .NET 4 introduces the AggregateException; an exception representing multiple exceptions. The AggregateException was introduced in the first place to be used with the parallel framework, but it can be used in other scenarios as well, such as batch operations.

Take a look at the following example..

I have a single action which I want to peform in batch. This single action might throw some exceptions.

private static void ExecuteSingleAction(int i)
{
      if (i == 5)            
            throw new ArgumentNullException("You forgot an argument.");       
      if (i == 18)
            throw new ArgumentException("This argument doesn't make sense.");
}

Most of the exceptions the single action might throw shouldn’t break my whole batch operation. While I’m executing the single actions I catch the exceptions which shouldn’t break the batch operation and hold them in a list of exceptions. The AggregateException has a public constructor taking an IEnumerable of exceptions. If I catch some exceptions while executing the single action I throw an AggregateException passing in that list of exceptions to its constructor.

private static void ExecuteBatch()
{
      List<Exception> exceptions = new List<Exception>();
      
      for (int i = 0; i < 100; i++)
      {
            try
            {
                  ExecuteSingleAction(i);
            }
            catch (ArgumentNullException nullRefEx)
            {
                  exceptions.Add(nullRefEx);
            }
            catch (ArgumentException argumentEx)
            {
                  exceptions.Add(argumentEx);
            }             
      }

      if (exceptions.Count > 0)           
            throw new AggregateException(exceptions);            
}

In the front-end I can catch the AggregateException, run over its InnerExceptions and act based on the type of exception.

static void Main(string[] args)
{
      try
      {
            ExecuteBatch();
      }
      catch (AggregateException aggEx)
      {
            foreach(Exception ex in aggEx.InnerExceptions)
            {                  
                  Console.WriteLine(ex.Message);

                  if (ex is ArgumentNullException)
                  {
                        //Do something
                  }

                  if (ex is ArgumentException)
                  {
                        //Do something else
                  }
            }
      }

      Console.ReadLine();
}

The result looks like this.

Can you imagine other scenarios where the AggregateException might be able to add some value?

Related post: Handling the AggregateException