Boost logo

Boost :

Subject: [boost] [program_options] Improving error text in exceptions
From: Leo Goodstadt (bunbun68_at_[hidden])
Date: 2011-11-13 15:58:48


As a long time fan of boost::program_options, I would very much like
to make the error messages in program_options exceptions more
consistent and informative.

Exception text is usually aimed at the developer as a diagnostic for
rare errors. If the exception needs to be propagated to the end-user,
it can be caught, and a more appropriate message substituted.

This is not true for program_options: Exceptions from invalid
program arguments are the common (and normal) reason for early program
termination.

It would be nice if, out of the box, exception text could be clear
enough to present to the end user more or less as is. This would allow
a single try/catch(exception) in main()
cerr << "Error: " << e.what() << "\n";
return 1;

>From the attached list of error messages, there are many, many
different exception types which are thrown. The usual practice of
repackaging / reformatting exceptions to be more user-friendly
would be tedious or impractical.

I grep-ed "boost::throw_exception" to get a list of all the exceptions
and messages.
I suggested revisions for all but 5. These I have set them aside
at the end.

I have modelled some of the proposed text on GNU genparse examples
(i.e. the behaviour of "ls" and "cat" etc.). These, by dint of their
frequent use / hammering by the huge linux user base, are probably
good examples of the sort of friendlier clarity I would hope for.

In some cases, I have tried to understand the exception text from the
code but might have misunderstood the original intent.

If this is useful, I shall painstaking go through the code and submit
a patch.

Leo Goodstadt

P.S. I realise there are pitfalls to do with option prefix styles "--"
and "/" but the addition of option prefixes to the exception text
makes the message a lot clearer.

P.P.S. I have kept the current style of starting the text in lower
case even though my own preference would be for a capitalised sentence
ending in a full stop.

=======================================================
Original (CURRENT) and revised (CHANGED) text resulting from
exception.what()
=======================================================
CURRENT: <ambiguous option option_name>
CHANGED: <option '--option_name' is ambiguous and matches options
"--aa"," --b" and "--c".>

// abbreviated instead of long/short because
// length might imply too many/few letters
CURRENT: <style disallows parameters for long options>
CHANGED: <arguments are not allowed for unabbreviated option names>

CURRENT: <style disallows parameters for short options>
CHANGED: <arguments are not allowed for abbreviated option names>

CURRENT: <style disallows all characters for short options>
CHANGED: <abbreviated option names are not valid>

CURRENT: <adjacent parameter is empty>
CHANGED: <Invalid command line syntax: each option with an equal sign
must be followed immediately by its argument.>

CURRENT: <parameters adjacent to long options not allowed>
CHANGED: <arguments are not allowed for unabbreviated options>

CURRENT: <required parameter is missing in 'option_name'>
CHANGED: <option '--option_name' requires an argument>

CURRENT: <in option 'option_name': invalid option value>
CHANGED: <invalid argument for option '--option_name'>

CURRENT: <unrecognised line in 'DODGY LINE'>
CHANGED: <options configuration file contained an invalid line: 'DODGY LINE'>

CURRENT: <multiple occurrences>
CHANGED: <option '--option_name' cannot be specified more than once>

CURRENT: <can not read file NON_EXISTENT_FILE_NAME>
CHANGED: <cannot read options configuration file 'FILE_NAME'>

CURRENT: <missing required option required_option>
CHANGED: <option '--option_name' is required>

CURRENT: <too many positional options>
CHANGED: <too many positional arguments have been specified>

CURRENT: <unknown option unknown_option>
CHANGED: <unrecognised option 'option_name'>

CURRENT: <in option 'invalid_option': invalid bool value>
CHANGED: <at least one argument is required for option '--option_name>

CURRENT: <in option 'option_name': invalid bool value>
CHANGED: <invalid argument for option '--option_name'.  Valid
arguments are 'on|off', 'yes|no', '1|0' and 'true|false'>

CURRENT: <in option 'option_name': multiple values not allowed>
CHANGED: <option '--option_name' only takes a single argument>

Not sure what these mean and have left them alone.

libs/program_options/src/parsers.cpp:112:
boost::throw_exception(error("long name required for config
file"));

libs/program_options/src/config_file.cpp:60:
boost::throw_exception(error("bad prefixes"));

libs/program_options/src/value_semantic.cpp:102:
boost::throw_exception(multiple_values());

libs/program_options/src/convert.cpp:66:
boost::throw_exception(std::logic_error("character conversion
failed"));

libs/program_options/src/convert.cpp:74:
boost::throw_exception(std::logic_error("character conversion
failed"));

libs/program_options/src/value_semantic.cpp:33:
boost::throw_exception(std::runtime_error("UTF-8 conversion not
supported."));

-- 
Dr. Leo Goodstadt
University of Oxford
United Kingdom

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk