0

When throwing exceptions in a class, is it the programmer's job to ensure this exception is caught in the class? Or is it best practice to assume this exception will be caught in the main file / runner program? I believe it is the latter, but I'm somewhat unsure.... take the following code:

#include <stdexcept>
#include <iostream>

using namespace std; // supposedly trustworthy duck

class Duck
{
public:
      Duck(int quack_nominee);
private:
      int quack_strength;
};

Duck::Duck(int quack_nominee)
{
     if (quack_nominee < 0)
     {
             throw runtime_error("A quack having a negative value produces undefined behavior on reality.");
     }

     quack_strength = quack_nominee;
}

Is the above code good practice? I'm assuming the runtime_error thrown will be caught somewhere. If the programmer using my class did not implement a try-catch block, the .exe file will crash (at least on my IDE and compiler).

Also, if I should have a try-catch block in the class itself, is it even possible to legally implement this?

Biffen
  • 6,249
  • 6
  • 28
  • 36
  • Your "errors" are called exceptions. – eesiraed Mar 03 '18 at 05:01
  • 4
    If an exception can be handled, it should be caught. If an exception cannot be handled, it should not be caught (unless it is caught, logged, and re-thrown). Consider an exception to be the morale equivalent of "abandon ship!". – Eljay Mar 03 '18 at 05:04
  • 1
    Oh, almost forgot: what exceptions should NOT be used for is flow control for non-exceptional situations. – Eljay Mar 03 '18 at 05:05
  • Possible duplicate of [Throwing exceptions from constructors](https://stackoverflow.com/questions/810839/throwing-exceptions-from-constructors) – xskxzr Mar 03 '18 at 05:13
  • 1
    In addition, for this specific code, using an `unsigned` parameter or just simply leaving it undefined (not recommended usually, only for efficiency purpose) are alternative ways depending on your intent. – xskxzr Mar 03 '18 at 05:16
  • IMO this is too broad because there is no one answer for all situations. Exceptions are for the exceptional and they should be caught at the point were the software can properly recover from the *whole operation* being performed at the time. – Galik Mar 03 '18 at 06:06
  • For boundary conditions you may want to look at `assert` which performs checks during the debugging phase but trusts the values in the release version. That's good for logical programming errors (bugs). They are zero cost so you can use them liberally and in places where you would never want an exception check (tight loops, hot inline functions etc...). – Galik Mar 03 '18 at 06:09
  • And, yes it is good practice to prevent objects being constructed with bad data. Catching in the class and *fudging* a "better" value that the programmer did not choose sounds a bit dubious to me... If you make it **impossible** for the programmer to construct an object with bad values, it is easier to reason on the correctness of the code. You know that everything that follows will be operating on a legal, well formed object. – Galik Mar 03 '18 at 06:11
  • 1
    In this case [`std::invalid_argument`](http://en.cppreference.com/w/cpp/error/invalid_argument) is probably a more suitable exception: _"reports errors that arise because an argument value has not been accepted"_. As opposed to [`std::runtime_error`](http://en.cppreference.com/w/cpp/error/runtime_error): _"reports errors that are due to events beyond the scope of the program and can not be easily predicted"_. –  Mar 03 '18 at 06:44
  • @Eljay Unfortunately that dogma is almost meaningless as stated. All it literally amounts it is 'don't throw exceptions unconditionally'. It has been widely abused to mean 'don't throw exceptions at end of file', for example. There is no cogent reason for this. The *original* meaning, for those who were around at the time, was not to use them as `gotos` within methods. Sadly, as always in this business, the original motivation is long forgotten, and it just becomes a cargo cult. – user207421 Mar 03 '18 at 07:36

1 Answers1

2

The whole point of exception is to terminate the execution flow of the function and to notify the caller of the error condition that cannot be handled within the function. So no, you definitely don't have to catch your own exceptions because it defeats the purpose of the exception.

Another question is what kind of errors you should report using exceptions. This is mostly depend on the specific use case but the most common cases are invalid input parameters or external errors (e.g. from OS or DB or anything outside your program) that cannot be handled within your function without violating the "principle of least surprise".

r3mus n0x
  • 5,954
  • 1
  • 13
  • 34