PR #2602 introduces assert macros that allow assertions even in release builds. In addition, these macros beautifully encapsulate file and line number in which the assertions occur providing a homogeneous interface across the entire code base.
Exceptions have a similar issue. The way in which exceptions are instantiated in Drake right now are not homogeneous across the code base.
For instance:
ERROR: preceding the message.Drake: <method name>: ERROR: <message>Drake: or ERROR: preceding the message.__FILE__ name and __func__ + message.Would it be a good idea/solution (inspired by #2602) to have a macro exception that would automatically append file, line and method name to the message? Something like (this is more like pseudocode):
class drake_exception_with_location: public std::exception {
public:
drake_exception_with_location (const char* msg, const char* func, const char* file, int line) {
message_ = "Error: at ";
message_ += file;
message_ += ":";
message_ += std::to_string(line);
message_ += " in " + std::string(func) + ": " + std::string(msg);
}
const char* what() const override {
return message_.c_str();
}
private:
std::string message_;
}
#define drake_exception(msg) drake_exception_with_location(msg, __func__, __FILE__, __LINE__);
which could be used as:
throw drake_exception("Explanatory message");
So #1935 already had some discussion on helping make throws-clauses clearer, but I was going to break that out into a separate issue anyway. I guess this issue can be the new home for the "make throwing more abbreviated and its results more descriptive" feature request.
Having gotten a few offline questions on this -- the example in the top post does not resemble my intent for this issue. Before I begin any work (timeframe undetermined), I will be sure to post a design outline here for review.
@jwnimmer-tri: great! provably the only "useful" part of my example is where it reads throw drake_exception("Explanatory message");, the rest is just pseudocode to start the discussion. Looking forward to this your design outline!
A few thoughts on standardized error message macros:
DRAKE_RUNTIME_ERROR("Can't open file %s\n", file_name);
DRAKE_RUNTIME_ERROR_UNLESS(file.good(), "Can't open file %s\n", file_name);
My tentative thought was to share the syntax from #1895 (logging) in the throw-helper. One less thing to learn.
You mean specifically the spdlog python-ish syntax?
Probably yes, though in general just "reuse whatever we choose for logging", even if that turns out to be something different than the python-ish spdlog. I think the mnemonic most often wanted for throwing is "log this verbose and helpful error, and then terminate" for which logging-like semantics will be best.
@jwnimmer-tri resolved this in #3219.
For the record, I think there is still lots of room for improvement, but I'm also fine with the issue being closed.