# V1067. Throwing from exception constructor may lead to unexpected behavior.

Анализатор обнаружил конструктор исключения, из которого может быть брошено другое исключение. Использование такого класса может привести к неожиданному поведению программы при обработке исключений.

Рассмотрим синтетический пример:

    #include <stdexcept>

    class divide_by_zero_error : public std::invalid_argument
    {
    public:
      divide_by_zero_error() : std::invalid_argument("divide_by_zero")
      {
        ....
        if (....)
        {
          throw std::runtime_error("oops!");   // <=
        }
      }
    };

    void example(int a, int b)
    {
      try
      {
        if (b == 0)
          throw divide_by_zero_error ();
        ....
      }
      catch (const divide_by_zero_error &e)
      {
        ....
      }

      // my_exception thrown and unhandled
    }

В коде функции 'example' программист пытается обработать возникшее исключение 'divide_by_zero_error', однако вместо этого будет сформировано исключение 'std::runtime_error' и не перехвачено последующим 'catch'-блоком. Это приведет к тому, что исключение покинет функцию 'example', что может привести к следующим ситуациям:

- исключение будет обработано другим обработчиком исключений выше по стеку вызовов, что также может не являться желаемым поведением;
- соответствующего обработчика исключений может не оказаться выше по стеку вызовов, и тогда программа будет аварийно завершена функцией 'std::terminate' как только исключение покинет функцию 'main'.

При разработке и использовании собственных классов исключений нужно проявлять особую бдительность, поскольку исключения в их конструкторах могут возникнуть в неожиданных местах, например при вызове других функций. В следующем примере при создании логирующего исключения может возникнуть второе исключение из функции 'Log':

    #include <ios>

    static void Log(const std::string& message)
    {
      ....
      // std::ios_base::failure may be thrown by stream operations
      throw std::ios_base::failure("log file failure");
    }

    class my_logging_exception : public std::exception
    {
    public:
      explicit my_logging_exception(const std::string& message)
      {
        Log(message); // <=
      }
    };

Данная диагностика классифицируется как:

CWE-755