
On 27 June 2012 21:46, Leo Goodstadt <leo.goodstadt@llew.org.uk> wrote:
To elaborate on what Volodya said, program_options is unusual (for Boost) library in its use of exceptions:
Most of the time, exceptions are there to inform the programmer of an error in the programme.
However, the majority of exceptions in program_options are there to indicate a problem in the construction of the command line by the *end-user* (not the programmer). In other words, the program *is* working exactly as designed. The programmer has no interest in the provenance of these exceptions *except* that they can be used to inform the end-user how they should retype the command line and try again.
It is entirely unhelpful for the end-user to have
Exception XXX on line xxx of file yyy....
I don't understand BOOST_THROW_EXCEPTION( ) to replace the output of .what() - but to supplement the output of boost::diagnostic_information( ), which I'm advocating for when the program is being tested by the development team. The diagnostics in my situation wouldn't be end-user visible. To make it easier to use program options *in English*, the exception
messages have been recently rewritten to be maximally informative to the end-user rather than the programmers. Thus we can take e.what() and write it out to std::cerr without further ado. Of course, for localisation, these error messages have to be reconstructed in the appropriate language. Hopefully, there is enough data in each exception to allow this.
The English messages are indeed an excellent touch, but I've noticed that error messages are one of the first things to be localised in a newly international product (I assume that they tend to be of a standard format which is easy for non-native speakers to implement). To handle multilingual output where specific exceptions are available is another instance where I'm going to want to look at the throw site to see how specific to the given case the exception types I'm catching actually are. Curiously, the current design of exceptions in program_options ended
up try to mirror what Emil has done in BOOST_THROW_EXCEPTION. When the exception is thrown deep in the bowels of the command line parsing, it does not have the full context which would allow an informative message to be constructed. The exception has to be propagated up, and then "decorated" before being rethrown.
I haven't worked with program_options code in a long while, so I'm unfortunately unfamiliar with the decorated info you're referring to - but it sounds similar in nature to the boost::error_info operators provided by boost::exception. The alternative was to pass the full context down the function call
hierarchy to each point at which exceptions can be thrown. This made the code horribly convoluted and ugly, and provoked loud cries of anguish from Volodya.
I understand the anguish, indeed; and I'm certainly not looking to cause more. Comparing exception strategies makes my head hurt at the best of times, and I don't presume to know what fits best with a library used by so many disparate projects.