Home > Net >  What is the correct exception to throw when a method is called at an inappropriate time?
What is the correct exception to throw when a method is called at an inappropriate time?

Time:10-15

I have a class which exposes a method which should be called a certain number of times by the user of the class. The amount of times the method is to be called is agreed upon via an int parameter during object construction. Thus, while calling it too few times could be due to the caller deciding to cancel the operation for whatever reason, calling it too often clearly qualifies as a programming error, i.e. std::logic_error. I was wondering whether there is a more concrete exception to be thrown in this situation, such as std::domain_error. This page on cppreference.com says std::domain_error is thrown in:

[...] situations where the inputs are outside of the domain on which an operation is defined

, which appears to match the use-case. However, I am asking because I am unsure whether a method call qualifies as "input" in this context. What exception should be thrown in this situation?

CodePudding user response:

What is the correct exception to throw when a method is called at an inappropriate time?

std::logic_error, preferably a struct/class deriving therefrom.

struct PixelOverflowException : public std::logic_error {
    PixelOverflowException() : std::logic_error("Cannot accept further pixels: resampled image is already complete.") {}
};

Deriving can be useful even for runtime exceptions (programming errors) because:

  • it will be easier to write tests checking the code's behavior in misuse scenarios.
  • if the caller wants to check for a specific exception for whatever reason, they'll be able to do so as well.
  • doing so has no cost. See https://stackoverflow.com/a/44901257/593146

std::domain_error

std::domain_error is a specific kind of std::logic_error that applies to situations where an operation is possible in theory, but not in practice. For example, a file format for photos might encode width and height as a 32-bit unsigned integer, meaning 4294967296 (if the encoded value is -1-biased) times 4294967296 = ‭18446744073709551616‬ pixels. A naive implementation of a decoder for such image format might be constrained to certain widths and heights, for example due to performing calculations involving width and height that will overflow long before the maximum width and height values occur.

uint32_t numPixels = width * height; // will overflow for width and height = 65536.

In such cases, the decoder should throw an exception deriving from std::domain_error instead of blindly engaging in undefined behavior: the file can theoretically be decoded, but the specific implementation is unable to do so.

std::domain_error is different from std::logic_error in that an implementation which does not need to throw it is without a doubt conceivable, if only in theory if need be.

To emphasize, both exceptions hint at an error on the caller's side, and std::domain_error does not necessarily indicate that an implementation is of poor quality or incomplete: the set of accepted inputs might be constrained on purpose for reasons of performance, usability or scope.

  • Related