How to fire multiple exceptions?

5
foreach (Foo el in arr) {
    // ...
    Validate(el);
    // ...
}

In the example code, when foreach is executed, an exception can be raised from the Validate function that will be handled in who called the method that contains the loop.

Exceptions triggered by Validate have to be handled by the user. The most convenient would be for the user to know all the errors that were thrown to correct them before re-executing the function that contains the loop. For this, I would have to do something like:

List<Exception> errors = new List<Exception>();

foreach (Foo el in arr) {
    // ...

    try {
        Validate(el);
    } catch(Exception e) {
        errors.Add(e);
    }

    // ...
}

if(erros.Any()) {
    throw errors; // somente objetos do tipo Exception podem ser disparados com throw.
}

How do I trigger multiple exceptions?

    
asked by anonymous 13.09.2017 / 16:48

2 answers

10

This seems like a conceptual error in the code.

Apparently you are using exceptions to handle validations and this is not only wrong but very bad, it is an extreme misuse of the exception engine.

Leaving this aside the short answer to your question is: Not possible.

Exceptions are for, as its name says, exceptional cases and not for validation of data or similar tasks.

Assuming you do not want to fix the code and stop using these exceptions, the best you can do is to pass that list of exceptions to the graphical interface layer and there do something to display the messages you want (or do what well understand).

But in this way, you can not capture them using a catch block.

It is still possible to fire a AggregateException based on the exception list and capture it. Something like:

To shoot:

if(erros.Any()) {
    throw new AggegateException("Mensagem", errors);
}

To capture:

catch (AggregateException ae) 
{
    ae.Handle((x) =>
    {
        // Todas as exceções dentro de 'ae' passarão por este bloco
        return true; // Isso impede a parada do código
    });
}

It may be interesting to read these publications:

Sample functional code with AggregateException . See working in .NET Fiddle.

using System;
using static System.Console;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        try
        {
            FazerAlgo();
        }
        catch (AggregateException ae)
        {
            ae.Handle((ex) =>
                      {
                          WriteLine(ex.Message);
                          return true;
                      });
        }
    }

    static void FazerAlgo()
    {
        throw new AggregateException("", new List<Exception>
                                     {
                                         new Exception("Erro 1"),
                                         new Exception("Erro 2")
                                     });
    }
}
    
13.09.2017 / 16:55
7

If you really want to throw several exceptions at a time for the code caller, use the class AggregateException , it receives a list of Exception .

I've tailored your code as example :

List<Exception> errors = new List<Exception>();

foreach (Foo el in arr) {
    // ...

    try {
        Validate(el);
    } catch(Exception e) {
        errors.Add(e);
    }

    // ...
}

if(erros.Any()) {
    throw new AggregateException(
        "Vários erros ocorreram durante a execução do método.",
        errors)
}
    
13.09.2017 / 17:28