1

In C++17, what is the proper pattern/approach to handling a collection of multiple exceptions?

Is there a C++ equivalent to C# AggregateException Class?

(I'm aware that exception as flow control is an anti-pattern.)

Eugene
  • 10,957
  • 20
  • 69
  • 97
  • Based on the shown C# code, this appears to be equivalent to `std::variant`. Or, perhaps a superclass, with `dynamic_cast` being used to interrogate whether it's an instance of a particular subclass. – Sam Varshavchik Nov 06 '18 at 02:24

2 Answers2

0

This is not common problem I see in c++. If you plan to use a library for multithread/multicore processing, you might wan't to check out what that library offers or how exceptions are handled. If you just need that sort of capability yourself you can do something like the following (pseudocode):

struct AggregateExcpetions {
  std::vector< std::variant< exception_type_1, exception_type_2, exception_type_3 > > m_exceptions;
}

Instead of using a variant it might be easier to just use a common base class - for example std::exception or perhaps std::runtime_error.

struct AggregateExcpetions {
  std::vector< std::unique_ptr<std::exception> > m_exceptions;
}
darune
  • 10,480
  • 2
  • 24
  • 62
0

As far as I'm concerned, there is no similar exception in C++.

You can write one by yourself.

I am using this one for saving errors on retrying operations.

When retrying operation exceeds its retry count, I aggregate exceptions into AggregateException and throw it.

    class AggregateException : public std::exception
    {
    public:
        explicit AggregateException(std::vector<std::exception> exceptions)
        {
            _exceptions = std::move(exceptions);

            std::stringstream whatString;
            whatString << "AggregateException:" << std::endl;
            for (auto const& ex : _exceptions){
                whatString << ex.what() << std::endl;
            }
            _whatMessage = whatString.str();
        }


        [[nodiscard]]
        const char* what() const noexcept override {
            return _whatMessage.c_str();
        }
    private:
        std::vector<std::exception> _exceptions;
        std::string _whatMessage;
    };

Usage example:

    std::vector<std::exception> exceptions;
    try
    {
        throw std::runtime_error("foo");
    } catch (const std::exception& ex){
        exceptions.emplace_back(ex);
    }
    try
    {
        throw std::runtime_error("bar");
    } catch (const std::exception& ex){
        exceptions.emplace_back(ex);
    }

    try
    {
        throw k_crm::AggregateException(exceptions);
    } catch (const std::exception& ex){
        std::cout << ex.what() << std::endl;
    }

Prints out:

AggregateException:
foo
bar
Kliment Nechaev
  • 480
  • 1
  • 6
  • 13