Avoiding throw because we are never sure they will be caught

  softwareengineering

I’m a junior in my company, and one of the rule coding rule they have is: “a constructor object must never fail” (i.e. never throw). So what if I give them a invalid parameter? Then, the object should be constructed anyway and there should be another way to check if the object is valid, like an isValid() method.

For the context, we are developing a desktop software (no web) in c++. I work mainly on the core of the app, which can be seen as a DLL used by the rest of the software.

I am surprised by this, and after a bit of questioning, I understand the following reasoning :

  1. When something throw, the caller has to handle this case (use try...catch)

  2. If a throw is not caught, stack unwinding will go all the way to the top, at which point it will encounter a global catch block that will do something like this : display the message “Something went horribly wrong”, try a session autosave, and shut down the app

  3. We cannot be sure that future programmers will correctly use your object and handle correctly all edge cases. If someone uses my object, forgets to add catch, and pass through testing, we are at risk of having a “Something went horribly wrong” message in production, and this should be avoided at all cost.

  4. So, an object constructor can never throw. In fact, no function should throw (outside of a very little part of the code that has a specific catch clause that doesn’t crash the app)

While I understand the reasoning, I find the consequences to be unsettling: I may not use exception.

And it’s a shame, because they are useful. Instead, we have a lot of if (myobj.isValid()) everywhere, and empty constructors alongside with init(....) methods, which I have a felling are a bad pattern.

But we can’t find a breach in this reasoning, especially point 3. Was would be a better approach, that allow programmers to throw when needed, and ensure that we never trigger the ultimate “Something went wrong” fail-safe ?


Basic example: if my object requires to store a size as a double, and size shall always be positive. But c++ doesn’t have unsigned double, so we have

class MyObj {
   MyObj(double size) {m_size = size};
   double GetSize() {return m_size};
   double m_size;
}

What if someone calls MyObj(-3) ? I can’t throw in the constructor, so the object must be created. Then, either I add a method bool isValid(){m_size>0;}, or the constructor does if(size<0){m_size = 0}.

In the first case, all caller have to check validity, it’s tedious. In the second case, I passed an error silently, which is not nice. What I want is have my object and always be sure that size is positive when I use it.

New contributor

sayanel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT