Drake: Implement a drake_exception capability

Created on 21 Jun 2016  路  9Comments  路  Source: RobotLocomotion/drake

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:

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");
backlog feature request

All 9 comments

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:

  • For error message generation it's important to support argument substitution in some form, for example
DRAKE_RUNTIME_ERROR("Can't open file %s\n", file_name);
  • It would be very nice to be able to check a condition at the same time (as for asserts):
DRAKE_RUNTIME_ERROR_UNLESS(file.good(), "Can't open file %s\n", file_name);
  • Stream-style formatting would be better, but no formatting should occur unless there is actually an error to report.
  • It isn't clear to me how much of FILE/LINE/func is useful to include in a message seen by an end user; those are certainly useful for developers but maybe their inclusion should be controllable (e.g. include in Debug; leave out in Release unless explicitly requested)?

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.

Was this page helpful?
0 / 5 - 0 ratings