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

The analyzer has detected an exception constructor that may throw another exception. Using such a class may cause the program to behave unexpectedly when handling exceptions.

Consider the following synthetic example:

    #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
    }

In the code of the 'example' function, the programmer intends the raised 'divide_by_zero_error' exception to be handled, but instead of it, an 'std::runtime_error' exception will be thrown, which will not be caught by the subsequent 'catch' block. As a result, the exception will leave the 'example' function, thus causing one of the following situations:

- the exception will be handled by another exception handler higher on the call stack, which may also be an undesired behavior;
- there could be no appropriate exception handler higher on the call stack, in which case the program will crash by calling the 'std::terminate' function as soon as the exception leaves the 'main' function.

Write and use custom exception classes with particular care because their constructors may throw exceptions at unexpected points – for example, when calling other functions. In the following example, when creating a logging exception, a second exception may be thrown by the 'Log' function:

    #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); // <=
      }
    };

This diagnostic is classified as:

CWE-755