7

In my code, a method is being called repeatedly within a loop like so:

foreach (var file in files)
{
    SomeMethod(file);
}

The method is likely to throw exceptions, but I don't want the code to exit the loop after the first exception.

Furthermore, the code above is being called from a web api controller, so I need a way to pass all the exception information back to the controller, where it will be handled (log exception and return error response to the client).

What I've done so far is catch and store all the exception in a list.

var errors = new List<Exception>();

foreach (var file in files)
{
    try
    {
        SomeMethod(file);
    }
    catch(Exception ex)
    {
        errors.Add(ex);
    }
}

Considering that rethrowing all the errors in the list is not an option, what is the best approach to return the exception information to the controller?

2
  • You can use string builder to concat messages from exception with information from loop itself. Then rethrow. Commented Apr 22, 2015 at 13:22
  • This wouldn't work if there are different exception types though, would it? Commented Apr 22, 2015 at 13:24

2 Answers 2

5

Use AggregateException.

You can pass the List<Exception> to its constructor and throw that.

At the end of your loop do:

AggregateException aggregateEx = new AggregateException(errors);
throw aggregateEx;

(or return AggregateException)

Sign up to request clarification or add additional context in comments.

4 Comments

I was about to write an answer with my own version of AggregateException... Should have checked the library first.
Thanks, throwing an AggregateException is probably what I'm looking for, will try and let you know. I don't know if returning an exception would be good practice. Also, what should I do when there is just one exception?
Yes returning exception is not a a good practice in general, (not sure about your situation though). It doesn't matter if you want to return a single exception or multiple. You can use AggregateException for both cases. But, if you are always expecting a single exception or want to break out in case of first exception then there is no need for AggregateException.
Thank you @Habib. I've added an answer with the solution that worked for me, but I will accept your answer as it was very helpful.
1

Based on Habib's suggestion, I've implemented a solution that also handles the case where there is just one exception. This way there are no unnecessarily nested exceptions.

if (errors.Any())
{
    if (errors.Count > 1)
    {
        throw new AggregateException("Multiple errors. See InnerExceptions for more details",errors);
    }
    else
    {
        ExceptionDispatchInfo.Capture(errors[0]).Throw();
    }
}

Simply rethrowing the single exception by calling throw errors[0]; should be avoided as it wouldn't preserve the stack trace of the original exception.

3 Comments

And are you sure that code you posted preserves the stacktrace? I really doubt it. You need to call the Capture in the catch block
I'm not sure, it's been over 4 years since I wrote the code. Did you try it out?
I did. ExceptionDispatchInfo.Capture needs to be called in the catch block in order to be able to actually capture all the info required for a proper throw(). So instead of a list of exceptions, you need a list of ExceptionDispatchInfo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.