program_options: informative exceptions

Dear Volodya, The version of Boost.program_options I am using throws lots of informative exceptions to indicate precisely what has gone wrong. The exception is where an incorrect argument to an option has been supplied e.g. --some_arg "abc" where --some_arg 0.6 is expected. The error message is annoyingly non-descript and it can be difficult to figure out which particular optional argument has been mis-specified. This imprecision is because when program_options::validation_error is being thrown, it is not clear which option is being parsed. Could I suggest that this particular exception is caught in: void store(const parsed_options& options, variables_map& xm, bool utf8) and the option context added back in (and the same exception type re-thrown): void store(const parsed_options& options, variables_map& xm, bool utf8) { ... // First, convert/store all given options for ( size_t i = 0; i < options.options.size(); ++i ) { const string& name = options.options[i].string_key; try { ... } catch ( validation_error& e ) { throw validation_error("[--" + name + "]: " + e.what()); } } ... } What do you think? Leo Goodstadt MRC Functional Genetics Unit University of Oxford

Hi Llew,
The version of Boost.program_options I am using throws lots of informative exceptions to indicate precisely what has gone wrong.
The exception is where an incorrect argument to an option has been supplied
e.g. --some_arg "abc" where --some_arg 0.6 is expected.
The error message is annoyingly non-descript and it can be difficult to figure out which particular optional argument has been mis-specified.
I agree with you.
This imprecision is because when program_options::validation_error is being thrown, it is not clear which option is being parsed.
Could I suggest that this particular exception is caught in: void store(const parsed_options& options, variables_map& xm, bool utf8) and the option context added back in (and the same exception type re-thrown):
catch ( validation_error& e ) { throw validation_error("[--" + name + "]: " + e.what()); }
}
... }
What do you think?
Personally, I would prefer something like: catch(validation_error& e) { e.set_option_name(name); throw; } However, that would require to format the string inside the 'what' method, something like: class validation_error { std::string m_option_name; std::string m_error_message; const char* what() const { m_error_message = logic_error::what(); if (!m_option_name.empty()) m_error_message = "--" + m_option_name + " : " + m_error_message; return m_error_message.c_str(); } }; I've used this approach once, but I'm not sure if has any hidden problems. I'd appreciate if some exception handling expert could comment on this. Thanks, Volodya

Hi Leo,
The exception is where an incorrect argument to an option has been supplied
e.g. --some_arg "abc" where --some_arg 0.6 is expected.
The error message is annoyingly non-descript and it can be difficult to figure out which particular optional argument has been mis-specified.
I've committed a change which cause the error message to look like: error: in option 'compression': invalid option value 'foo' what do you think? Then only problem is the case where an option has a short version: if you run ./first -c foo then the error message will be exactly the same, which requires the user to mantally link "-c" to "compression". Do you think it's a problem? Thanks for bringing up this issue! - Volodya

Dear Volodya,
I've committed a change which cause the error message to look like:
error: in option 'compression': invalid option value 'foo'
what do you think? Then only problem is the case where an option has a short version: if you run
./first -c foo
then the error message will be exactly the same, which requires the user to mantally link "-c" to "compression". Do you think it's a problem?
There are always going to be problems where the option name was not fully specified on the command line (e.g. --compre 'foo') and I had first wondered if it would be possible to echo what was actually typed in. This proved to be too much effort.. Otherwise you would actually have to remember the parsed item as well as which option it mapped to... Do you think option '--compression' is clearer? Thanks for your time Leo

Hi Leo,
Dear Volodya,
I've committed a change which cause the error message to look like:
error: in option 'compression': invalid option value 'foo'
what do you think? Then only problem is the case where an option has a short version: if you run
./first -c foo
then the error message will be exactly the same, which requires the user to mantally link "-c" to "compression". Do you think it's a problem?
There are always going to be problems where the option name was not fully specified on the command line (e.g. --compre 'foo') and I had first wondered if it would be possible to echo what was actually typed in. This proved to be too much effort.. Otherwise you would actually have to remember the parsed item as well as which option it mapped to...
I think that technically, this is possible. At least the command line parser itself provides this information. It's just not stored in the 'basic_option' class. I'll think about this more.
Do you think option '--compression' is clearer?
In the current situation, no. Since the command line can contain "-c", or even "/compression", using specific syntax in error message will just add to confusion. If we're going to show the exact name specified on the command line, then well, we'll show the syntax used there. Thanks, Volodya
participants (2)
-
Llew Sion Goodstadt
-
Vladimir Prus