Exception class with a char* constructor

Opinion plays a role here. The problem is that std::exception does not have a constructor that takes a string argument; this is an MSVC extension. I see two ways to go about it:

  1. Don’t pass a string argument
  2. Don’t use std::exception

The first case is straightforward; just use

throw std::exception();

The drawback is that you don’t get a descriptive error message.

If the error message is important, using std::exception directly is not an option. In this case, you could use either std::logic_error or std::runtime_error, which inherit std::exception and do have constructors taking a string argument, so

throw std::runtime_error("Unable to format Device");

might already solve the problem. catch clauses that caught the std::exception will also catch the std::runtime_error. There is one potential problem, though: catch clauses that catch std::runtime_error would not have caught the std::exception but will catch this one.

This seems like a bit of a corner case, and it is entirely possible that it is not a problem for you. If, however, there is a possibility that along the call stack there is a catch clause that catches std::runtime_error but should not catch the exception thrown by this code, you could derive your own exception class from std::exception that does take a string argument. Because the class is new, it will not be caught by existing catch clauses. For example:

class descriptive_exception : public std::exception {
public:
  descriptive_exception(std::string const &message) : msg_(message) { }
  virtual char const *what() const noexcept { return msg_.c_str(); }

private:
  std::string msg_;
}

And then

throw descriptive_exception("Unable to format Device");

This is arguably not very pretty, and it is unlikely that it is necessary, so the more probable solution is to use std::runtime_error or std::logic_error (or a class derived from one of them).

Whether std::logic_error or std::runtime_error is more appropriate is not very clear-cut; in this case I’d probably go with std::runtime_error because the error does not seem even theoretically predictable, but given that std::domain_error and std::future_error derive from std::logic_error, it would not be entirely out of place in that hierarchy. This is, I think, a matter of opinion.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)